Що спричиняє помилку MySQL 1062 - дублікат запису при запуску ведомого?


11
  • Версія MySQL Master: 5.5.16-1
  • Версія Slave MySQL: 5.5.18-1

Знімок майстра створюється:

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

Цей дамп-файл імпортується на підлеглий (який запускається з --skip-slave-startопцією) без помилок:

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

Але я отримав таку помилку при виконанні 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, ...

На майстрі є лише один запис з ідентифікатором 115846:

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

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

Спробуйте пропустити деякі запити за допомогою:

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

не допомогло. Я не хочу пропускати ці помилки, додаючи:

slave-skip-errors = 1062

до my.cnfфайлу , так як це може привести рабські несумісне.

Що може бути причиною цієї помилки?


ОНОВЛЕННЯ

Як правило, я не налаштовую реплікацію mySQL

Які кроки, на вашу думку, я не дотримуюся документа?

Цікаво, чи не зіткнеться ви з тією ж проблемою, якщо ви мали б налаштувати всю конфігурацію, а не передачу команди mysqldump.

Ні, це працює як зазвичай, якщо я також зміню головний на відповідні координати.

Я б спробував скинути базу даних на підлеглий, переконайтесь, що бінлоги чисті, і почати заново. Також перевірте таблицю, про яку йдеться, у майстрі, щоб переконатися, що в індексах немає помилок.

Чи достатньо видалити (перемістити) всі даніDir? Я це зробив і отримав такий же результат.


Відповідь на @Dmytro Leonenko

'показати статус підлеглого \ G' на підлеглому, щоб переконатися, що він правильно налаштований, MASTER_LOG_POS дорівнює 0

Тільки "показ статусу раба \ G" після імпорту, але перед "запуском підлеглого;" може дати нам відповідь

Я створив резервну копію datadir, видаляю всі та запускаю mysql_install_db, імпортую дамп-файл, виконую change master toі ось результати:

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)

Мені цікаво, чому Master_Log_Pos дорівнює 4?


1
З цим ідентифікатором може бути лише один запис, отже, помилка, вона ніколи не запишеться. Коли ви видаєте, SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1чи змінюється запит, що викликає помилку, щонайменше? Чи правильно було налаштовано положення бійнлогів для підлеглого?
thinice

Щоразу, коли я пропускаю лічильник, він змінюється на інший ідентифікатор. --master-dataВаріант вже записати виконавчі координати лог в файл дампа. Мені потрібно лише змінити master на master_host, master_user, master_password.
кванта

Як правило, я не налаштовую реплікацію mySQL (я зазвичай налаштовую реплікацію за URL-адресою тут: dev.mysql.com/doc/refman/5.0/en/replication-howto.html ) Однак, читаючи параметри mysqldump, немає причин. чому це не повинно працювати. Цікаво, чи не зіткнеться ви з тією ж проблемою, якщо ви мали б налаштувати всю конфігурацію, а не передачу команди mysqldump.
Ріліндо

Ви маєте на увазі, що я не повинен використовувати цю --master-dataопцію під час створення знімка даних? Якщо це все-таки трапляється, коли я використовую --lock-all-tablesопцію, і change master to master_log_file='', master_log_pos='', ...які можуть бути причини?
кванта

Ні, це не те, що я говорю. Як я нагадав, те, що ви зробили, має бути роботою за призначенням - наскільки я бачу, немає жодної помилки з цим варіантом. Однак це не означає, що цього немає, тому, як крок ізоляції, я б дотримувався конвенції, наданої mySQL спочатку через цю URL-адресу. т. Якщо це працює, принаймні, ви маєте вказівки розпочати усунення несправностей. Якщо цього не відбувається, ну, у нас інша проблема. :)
Ріліндо

Відповіді:


7

Що спробувати вирішити свою проблему:

  1. Спершу слід видалити master.info на підлеглому і перезапустити mysql
  2. видати ЗМІНИ МАЙСТЕР MASTER_HOST = 'XX.XX.XX.XX', MASTER_USER = 'repl', MASTER_PASSWORD = 'slavepass';
  3. зробіть mysqldump з параметром '--flush-logs' на майстрі
  4. 'mysql -u user -p <dump.sql' на підлеглому
  5. 'показати статус підлеглого \ G' на підлеглому, щоб переконатися, що він правильно налаштований, MASTER_LOG_POS дорівнює 0
  6. 'почати раб;' на раба.

Що також перевірити:

  • Формат бінарного файлу: змішаний
  • server_ids відрізняються на master і slave

Видача цілого основного рядка зміни (включаючи ім’я журналу та номер позиції) насправді виправляє його, але в цей момент, я думаю, що основне питання полягає в тому, чому Quanta доведеться знову вводити ім’я журналу та номер позиції, коли це вже знаходиться в дамп-файл.
Ріліндо

Тільки "показ статусу раба \ G" після імпорту, але перед "запуском підлеглого;" можна дати нам відповідь
Дмитро Леоненко

додав запитувану інформацію до моєї оригінальної публікації.
кванта

Як ви закінчилися з "Master_Host: xxxx Master_User: xx", не видавши "CHANGE MASTER ...". Або ви просто не згадали про це у відповіді? Ви перевірили формат binlog і яким був командний рядок для mysqldump?
Дмитро Леоненко

Я вже згадував, що у своєму дописі " імпортуйте дамп-файл, виконайтеchange master to ". Я використовую MIXED-журнал. Я тестував MySQL 5.0.77 (на основі тверджень), це також спричиняє цю помилку. Повний туздИшпр цеmysqldump -u root -p --all-databases --master-data --flush-logs > alldb_$(date +%F).sql
кванти

2

Проблема викликана встановленням майстра на працюючий сервер виробництва ДО ПЕРЕД виконання дамп (наскільки я можу сказати). Отже, є запити, написані в master_log, які вже виконані на даних, що зберігаються на підлеглому. Я ніколи не бачив рішення на веб-сайті mysql або списку розсилки. Отже, я придумав таке рішення, яке вирішило мою проблему.

на рабі:

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

на майстра:

mysql> RESET MASTER;

на рабі:

mysql> RESET SLAVE;
mysql> START SLAVE;

до речі, я забігав на смітнику з наступним:

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

Я сподіваюся, що це допомагає комусь іншому.

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

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


відредаговано, щоб включити ПЛАТНІ ПРИВИЛЕГИ; Після чергової помилки я зрозумів, що навіть мої користувачі були імпортовані з дампа, їхні привілеї ще не були активними.
BroknDodge

RESET MASTER слід працювати на рабі, а не на господареві, див. Percona.com/blog/2013/02/08/…
Jon

1

Якщо ви не хочете, щоб REDO пройшов повну процедуру, було б корисним виправленням

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

Якщо таких помилок занадто багато, непоганою ідеєю було б автоматизувати її за допомогою скрипту bash.

Посилання: Виправлення помилки повторюваної копії


1

У мене була точна проблема, і посилання Ut xd допомогло. але команда в цьому посиланні мала синтаксичну помилку, і ось версія, яка працювала для мене:

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

По суті, він перевіряє наявність дублікальної помилки входу та пропускає цю подію від головного. і робити це в петлі.


1
Це було б набагато кращою відповіддю, якби ви пояснили, що робить цей код і відформатували код, щоб він був більш читабельним.
kasperd

0

У моєму випадку питання вирішується наступними командами

виконавши наступні кроки

STOP SLAVE;
RESET SLAVE;
START SLAVE;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.