Tidak dapat memulihkan (kesalahan 3456)

9

Saya memiliki situasi yang tidak mudah dipecahkan, dan saya pikir saya akan bertanya di forum ini jika ada orang lain yang memiliki saran.

Saya menjalankan SQL Server 2008 R2 Standard SP3 pada Windows Server 2008R2 Enterprise.

Basis data membutuhkan beberapa pemeliharaan, dan setelah itu saya perlu memulihkan di server lain. Saya memiliki cadangan db penuh yang dilakukan dengan COPY_ONLY ditambah satu set cadangan 4 tlog.

  1. sebelum memulai, buat tlogbackup1
  2. berubah dari FULLke BULK_LOGGEDmodel pemulihan
  3. tambahkan filegroup baru
  4. tambahkan file ke newfilegroup
  5. atur newfilegroup menjadi default
  6. pilih ke dalam tabel (di newfilegroup)
  7. jatuhkan meja asli
  8. hapus file asli
  9. hapus filegroup asli
  10. ubah nama tabel baru agar sesuai dengan tabel asli
  11. ubah nama file newfilegroup agar sesuai dengan filegroup asli
  12. ubah nama file dalam katalog agar sesuai dengan nama file asli
  13. ubah nama file pada level OS untuk mencocokkan nama file asli
  14. atur filegroup default menjadi yang asli
  15. bawa db online
  16. berubah dari BULK_LOGGEDke FULLmodel pemulihan
  17. Setelah semua langkah selesai, buat tlogbackup2

Pemulihan semua cadangan harus menggunakan WITH MOVE, karena perubahan huruf drive di server pemulihan.

Langkah pemulihan:

RESTORE database SomeDB FROM DISK = 'D:\REPRO\SomeDB.bak'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup1.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

RESTORE LOG SomeDB FROM DISK = 'D:\REPRO\tlogbackup2.trn'   
WITH 
MOVE 'SystemData' TO 'D:\SQLDATA\SomeDB.mdf'
,MOVE 'SystemDataPDS' TO 'D:\SqlData\SomeDB.ndf'
,MOVE 'SystemData_log' TO 'D:\SQLLogs\SomeDB.LDF'
,NORECOVERY
,stats = 1

Pemulihan tlog akhir mencapai 100% dan kemudian gagal dengan kesalahan 3456:

Diproses 368 halaman untuk database 'SomeDB', file 'SystemData' pada file 1.

Diproses 7656520 halaman untuk database 'SomeDB', file 'SystemDataPDS' pada file 1.

Diproses 172430 halaman untuk database 'SomeDB', file 'SystemData_log' pada file 1.

Msg 3456, Level 16, Negara 1, Baris 1
Tidak dapat mengulang catatan log (210388: 123648: 232), untuk ID transaksi (0: 1016710921), di halaman (4: 8088), database 'SomeDB' (ID database 6) . Halaman: LSN = (0: 0: 1), jenis = 11. Log: OpCode = 4, konteks 11, PrevPageLSN: (210388: 122007: 1). Pulihkan dari cadangan database, atau perbaiki database. Msg 3013, Level 16, Status 1, Jalur 1 LOG RESTORE berakhir secara tidak normal.

Hanya untuk memverifikasi bahwa cadangan db penuh baik-baik saja, saya mengembalikannya berlari CHECKDB, dan tidak ada kesalahan.

Semua umpan balik disambut.

Terima kasih sebelumnya,

Ned Otter

NedOtter
sumber
1
Bisakah Anda menguraikan mengapa Anda pikir Anda memiliki rantai log yang tidak terputus? Saat Anda membalik basis data ke mode BULK_LOGGED dan mulai mengacaukan skema, semua taruhan agar rantai log tidak terputus dimatikan.
Thomas Kejser
Terima kasih atas balasan Anda, Thomas. Saya melihat sekarang bahwa judul posting saya salah. Saya tidak membutuhkan titik pemulihan waktu, tetapi pemulihan penuh ke akhir cadangan tlog ke-4. Jadi pengaturan BULK_LOGGED seharusnya tidak menyebabkan masalah dengan itu. Saya tidak melihat bagaimana apa yang saya lakukan akan menyebabkan cadangan tlog ke-2 gagal - semua perintah didukung oleh SQL Server, dan saya menjalankan langkah-langkah yang persis sama (meskipun tidak pada data yang sama) pada database yang lebih kecil, dan dapat untuk mengembalikan cadangan tlog ke-2 tanpa masalah.
NedOtter
Kesalahannya terlihat seperti korupsi. Ini adalah kesalahan internal. Bisakah Anda memverifikasi integritas semua file cadangan? Apakah mereka dengan checksum?
usr
Saya memang memverifikasi bahwa cadangan db penuh memiliki 0 kesalahan dengan menjalankan CHECKDB. Saya harus memeriksa untuk melihat apakah CHECKSUM digunakan.
NedOtter
1
Jika cadangan mengaktifkan checksum, maka Anda juga harus menggunakan checksum untuk pemulihan. Tipe halaman 11 adalah halaman PFS, yang berarti Anda tidak dapat memperbaikinya, Anda hanya dapat melakukan pengembalian penuh. Juga, Anda tidak mengatakan kapan salinan cadangan saja diambil. Di mana cadangan itu dalam garis waktu?
Robert L Davis

Jawaban:

9

Untuk memahami mengapa kesalahan 3456 dilemparkan, kita perlu mengambil sedikit langkah mundur dan memahami bagaimana SQL Server menangani sudut pemulihan ini.

Ketika SQL Server mengulang operasi, dan mengulang itu adalah modifikasi halaman, itu membuat pemeriksaan cepat. Di header halaman pada akhirnya akan ada PageLSN, yang merupakan indikasi dari LSN terakhir yang telah memodifikasi halaman itu, direkam oleh halaman. Pikirkan seperti ini, halaman melacak LSN terakhir yang telah melakukan modifikasi padanya. Ini adalah PageLSN.

Setiap kali ada operasi modifikasi halaman yang dicatat, catatan log itu mencakup beberapa LSN. Yaitu, catatan log LSN (pikirkan ... LSN saat ini ), dan kemudian memiliki apa yang disebut LSN Halaman Sebelumnya ( PrevPageLSNmaju). Jadi ketika kami memodifikasi halaman, salah satu bagian data yang dimasukkan ke dalam catatan log adalah apa yang ditunjukkan halaman tersebut sebagai LSN terakhir sebelum Anda memodifikasi halaman .

Pikirkan seperti ini ... Mobil Anda perlu dikerjakan di atasnya. Mechanic John bekerja pada mobil Anda, dan di ruang mesin memiliki tag kecil dan Mechanic John menulis "John mengerjakan mobil ini terakhir". Kemudian pada saat Anda membawa mobil Anda ke toko lain, Mechanic Mark melihat di ruang mesin dan melihat bahwa Mechanic John bekerja pada mobil ini terakhir. Di lembar datanya ia menulis informasi ini. Ide yang sama dengan SQL Server.

Ini bisa agak membingungkan, jadi lihat gambar ini di bawah ini pada modifikasi halaman berurutan, dan bagaimana PageLSNdan PrevPageLSNhubungannya:

masukkan deskripsi gambar di sini

Mari kita berputar kembali, karena ini semua berperan ketika Anda perlu mengulang operasi pada halaman (mengembalikan, memulihkan, HA, dll.). Ketika SQL Server perlu mengulang operasi halaman, itu membuat pemeriksaan kewarasan untuk melihat apakah PageLSNpada halaman cocok dengan PrevPageLSNyang dicatat oleh catatan log. Jika itu tidak sama, maka Anda akan melihat kesalahan 3456 dilemparkan.

Apakah PageLSN sama dengan PrevPageLSN ? Tidak??? Hentikan dan bangkitkan kesalahan 3456 ...

Mari kita menganalisis pesan kesalahan Anda, yang mencakup caranya:

Tidak dapat mengulang catatan log (210388: 123648: 232), untuk ID transaksi (0: 1016710921), di halaman (4: 8088), database 'SomeDB' (ID database 6). Halaman: LSN = (0: 0: 1) , jenis = 11. Log: OpCode = 4, konteks 11, PrevPageLSN: (210388: 122007: 1) . Pulihkan dari cadangan database, atau perbaiki database. Msg 3013, Level 16, Status 1, Jalur 1 LOG RESTORE berakhir secara tidak normal.

Saya telah berani dua potongan data yang memiliki ketidaksetaraan menyebabkan kesalahan. Anda dapat melihat bahwa kami PageLSNadalah 0: 0: 1 (ini ditemukan di header halaman), dan kami PrevPageLSNadalah 210388: 122007: 1 (ini ditemukan dalam data pada catatan log yang berusaha untuk diulang). Ini jelas tidak sama, maka err3456.

Jadi untuk mencari tahu mengapa acara ini, akan mencari tahu mengapa ada perbedaan di sini. Kita benar-benar perlu melacak siklus hidup halaman 4: 8088 dan melihat di mana putuskan hubungan itu. Sayangnya tanpa informasi lebih lanjut, atau pemecahan masalah langsung tidak ada lagi yang bisa saya lakukan selain memberi Anda latar belakang operasi pemulihan ini dan apa yang menyebabkan kesalahan.

Thomas Stringer
sumber
Saya tahu ini sudah lama tapi masih ... bagus, terima kasih untuk penjelasannya!
RThomas