Apa yang menyebabkan kesalahan MySQL 1062 - entri duplikat ketika memulai slave?

11
  • Versi MySQL Master: 5.5.16-1
  • Versi MySQL Slave: 5.5.18-1

Cuplikan master dibuat oleh:

mysql> FLUSH TABLES WITH READ LOCK;
shell> mysqldump --all-databases --master-data > dbname_`date +%F`.sql

File dump ini diimpor pada slave (yang dimulai dengan --skip-slave-startopsi) tanpa kesalahan:

shell> pv dbname_`date +%F`.sql | mysql -u root -p

Tapi saya mendapat kesalahan berikut ketika menjalankan mysql> start slave;:

    Last_SQL_Errno: 1062
    Last_SQL_Error: Error 'Duplicate entry '115846' for key
'PRIMARY'' on query. Default database: 'db'. Query: 'INSERT INTO
request_posted (id, user_id, channel, message, link, picture, name, ...

Hanya ada satu catatan dengan ID 115846 di master:

mysql> select count(*) from request_posted where id=115846;
Current database: db

+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.01 sec)

Cobalah untuk melewatkan beberapa pertanyaan dengan:

mysql> STOP SLAVE; 
mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; 
mysql> START SLAVE;

tidak membantu. Saya tidak ingin melewatkan kesalahan itu dengan menambahkan:

slave-skip-errors = 1062

ke my.cnffile karena mungkin membawa budak tidak konsisten.

Apa yang mungkin menjadi alasan untuk kesalahan ini?


MEMPERBARUI

Ini bukan bagaimana saya biasanya mengatur replikasi mySQL

Langkah mana yang Anda pikir saya tidak ikuti dokumen?

Saya bertanya-tanya apakah Anda akan menghadapi masalah yang sama jika Anda harus mengatur seluruh konfigurasi daripada melewati perintah mysqldump.

Tidak, ini berfungsi seperti biasa jika saya juga mengubah master ke koordinat yang sesuai.

Saya akan mencoba menjatuhkan database pada slave, pastikan binlog sudah jelas, dan mulai lagi. Periksa juga tabel yang dimaksud pada master untuk memastikan indeks tidak memiliki kesalahan.

Apakah menghapus (memindahkan) semua datadir sudah cukup? Saya melakukan itu dan mendapatkan hasil yang sama.


Membalas @Dmytro Leonenko

'tampilkan status budak \ G' pada budak untuk memastikan bahwa itu dikonfigurasikan dengan benar, MASTER_LOG_POS adalah 0

Hanya 'tampilkan budak patung \ G' setelah impor tetapi sebelum 'mulai budak;' dapat memberi kita jawabannya

Saya mencadangkan datadir, menghapus semua dan menjalankan mysql_install_db, mengimpor file dump, mengeksekusi change master todan inilah hasilnya:

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: x.x.x.x
                  Master_User: xx
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 106
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
1 row in set (0.00 sec)

Saya bertanya-tanya mengapa Master_Log_Pos adalah 4?

kuanta
sumber
1
Hanya ada satu catatan dengan id itu, maka kesalahannya, itu tidak akan pernah ditulis. Kapan Anda mengeluarkan SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1Apakah permintaan yang menyebabkan kesalahan berubah sedikit? Apakah pengaturan posisi slave binlog sudah benar?
thinice
Setiap kali saya melewati penghitung, itu berubah ke ID lain. The --master-dataopsi sudah menulis koordinat log biner ke file dump. Saya hanya perlu mengubah master ke master_host, master_user, master_password.
quanta
Ini bukan bagaimana saya biasanya mengatur replikasi mySQL (saya biasanya menyiapkan replikasi per URL di sini: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ) Namun, membaca opsi mysqldump, tidak ada alasan mengapa itu tidak berhasil. Saya bertanya-tanya apakah Anda akan menghadapi masalah yang sama jika Anda mengatur seluruh konfigurasi daripada melewati perintah mysqldump.
Rilindo
Maksud Anda, saya seharusnya tidak menggunakan --master-dataopsi ini saat membuat snapshot data? Jika masih terjadi ketika saya menggunakan --lock-all-tablesopsi dan change master to master_log_file='', master_log_pos='', ..., apa penyebabnya?
quanta
Tidak, bukan itu yang saya katakan. Seperti yang saya singgung, apa yang telah Anda lakukan harus berfungsi sebagaimana dimaksud - sejauh yang saya bisa lihat, tidak ada bug yang ada dengan opsi itu. Namun, itu tidak berarti bahwa tidak ada, jadi sebagai langkah isolasi, saya akan mengikuti konvensi yang disediakan oleh mySQL terlebih dahulu melalui URL itu. t. Jika berhasil, setidaknya Anda memiliki arah untuk memulai pemecahan masalah. Jika tidak, kita punya masalah lain. :)
Rilindo

Jawaban:

7

Apa yang harus dicoba untuk memperbaiki masalah Anda:

  1. Anda harus menghapus master.info pada slave terlebih dahulu dan restart mysql
  2. masalah CHANGE MASTER TO MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass';
  3. lakukan mysqldump dengan opsi '--flush-logs' pada master
  4. 'mysql -u pengguna -p <dump.sql' di slave
  5. 'tampilkan status budak \ G' pada budak untuk memastikan bahwa itu dikonfigurasikan dengan benar, MASTER_LOG_POS adalah 0
  6. 'mulai budak;' pada budak.

Apa yang harus diperiksa juga:

  • Format binlog: CAMPURAN
  • server_ids berbeda pada master dan slave
Dmytro Leonenko
sumber
Mengeluarkan seluruh string master perubahan (termasuk nama log dan nomor posisi) benar-benar memperbaikinya, tetapi pada titik ini, saya pikir pertanyaan inti adalah mengapa Quanta harus memasukkan kembali nama log dan nomor posisi saat yang sudah ada di buang file.
Rilindo
Hanya 'tampilkan budak patung \ G' setelah impor tetapi sebelum 'mulai budak;' dapat memberi kita jawabannya
Dmytro Leonenko
menambahkan info yang diminta ke dalam posting asli saya.
kuanta
Bagaimana Anda berakhir dengan "Master_Host: xxxx Master_User: xx" tanpa mengeluarkan "CHANGE MASTER ...". Atau Anda tidak menyebutkannya sebagai jawaban? Sudahkah Anda memeriksa format binlog dan apa baris perintah untuk mysqldump?
Dmytro Leonenko
Saya sudah menyebutkan bahwa dalam posting saya " impor file dump, jalankanchange master to ". Saya menggunakan logging berbasis MIXED. Saya sudah menguji dengan MySQL 5.0.77 (berbasis pernyataan), itu juga menyebabkan kesalahan ini. Mysqldump penuh adalahmysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
quanta
2

Masalahnya disebabkan oleh pengaturan master pada server produksi yang berjalan SEBELUM melakukan dump (sejauh yang saya tahu). Jadi, ada pertanyaan yang ditulis dalam master_log yang telah dieksekusi pada data yang berada di slave. Sebenarnya saya tidak pernah melihat solusi di situs web mysql atau milis. Jadi, saya datang dengan solusi berikut yang memecahkan masalah saya.

pada budak:

mysql> STOP SLAVE;
mysql> FLUSH PRIVILEGES;  # dump likly included users too

pada master:

mysql> RESET MASTER;

pada budak:

mysql> RESET SLAVE;
mysql> START SLAVE;

Omong-omong, saya menjalankan dump saya dengan yang berikut pada slave:

mysqldump -uROOTUSER -pROOTPASSWORD -hMYSQLMASTER.EXAMPLE.COM --all-databases --delete-master-logs | mysql -uROOTUSER -pROOTPASSWORD

Saya harap ini membantu orang lain.

http://dev.mysql.com/doc/refman/5.0/en/reset-master.html

http://dev.mysql.com/doc/refman/5.0/id/reset-slave.html

BroknDodge
sumber
diedit untuk memasukkan PRIVILEGUS FLUSH; Saya menyadari setelah kesalahan lain bahwa bahkan pengguna saya telah diimpor dengan dump, hak istimewa mereka belum aktif.
BroknDodge
RESET MASTER harus dijalankan pada slave, bukan pada master, lihat percona.com/blog/2013/02/08/…
Jon
1

Jika Anda tidak ingin mengulangi prosedur lengkap, perbaikan yang baik akan digunakan

STOP SLAVE;    
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;

Jika ada terlalu banyak kesalahan seperti itu, ide yang bagus adalah mengotomasinya menggunakan skrip bash.

Ref: Memperbaiki Kesalahan Entri Duplikat

Ut xD
sumber
1

Saya memiliki masalah yang tepat dan tautan Ut xd membantu. tetapi perintah di tautan itu memiliki kesalahan sintaks dan ini adalah versi yang berfungsi untuk saya:

while [ 1 ]; do if [ `mysql -uroot -ppassword -e"show slave status \G;" | grep "Duplicate entry" | wc -l` -eq 2 ] ; then mysql -uroot -ppassword -e"stop slave; set global sql_slave_skip_counter=1; start slave;"; fi; sleep 1; mysql -uroot -ppassword -e"show slave status\G"; done

Ini pada dasarnya memeriksa apakah ada kesalahan entri duplikat dan melewatkan acara ini dari master. dan melakukannya dalam satu lingkaran.

perlwle
sumber
1
Ini akan menjadi jawaban yang jauh lebih baik jika Anda akan menjelaskan apa kode itu dan memformat kode agar lebih mudah dibaca.
kasperd
0

Dalam kasus saya, masalah ini diselesaikan dengan perintah berikut

dengan langkah-langkah berikut

STOP SLAVE;
RESET SLAVE;
START SLAVE;
Karthik
sumber