MySQL InnoDB 로그에서“미래에”더 나은 방법은 무엇입니까?


16

MySQL 5.0 에서이 InnoDB 오류가 발생했습니다. Mysqld는 완전히 중지되었지만 나중에 ib_logfile0 & ib_logfile1을 잃어 버렸습니다. 이제 깨끗하게 시작한 후 InnoDB는 "충돌 복구"를 수행했습니다. innodb_force_recovery = 4 비즈니스를 진행하고 중단 된 MyISAM 테이블을 복구했으며 이제이 외에도 복제를 수행 할 수 있습니다. 큰 숫자는 기념했다 :

111116 15:49:36  InnoDB: Error: page 393457 log sequence number 111 561,760,232
InnoDB: is in the future! Current system log sequence number 70 3,946,969,851.
InnoDB: Your database may be corrupt or you may have copied the InnoDB
InnoDB: tablespace but not the InnoDB log files. See
InnoDB: http://dev.mysql.com/doc/refman/5.0/en/forcing-recovery.html
InnoDB: for more information.

이것은 슬레이브 서버에 있습니다. 위의 오류는 수백 가지가 뿜어냅니다. 이 답변을 찾았습니다 : "삽입 및 삭제> 64GB 상당의 데이터, 로그 시퀀스 번호가 충분히 부풀려집니다".

http://forums.mysql.com/read.php?22,50163,50163#msg-50163

64GB의 마법 번호는 4GB * 16에서 나옵니다.이 사람의 innodb 로그 "주요 번호"는 0에서 15로 증가해야했습니다. 광산은 70에서 111 = 164GB로 증가합니다. 5 일이 소요됩니다. 스크립트 속도를 높이고 속도를 높이기 위해 병렬로 실행합니다. 그 동안 다른 사람이 더 나은 답변을 기대하고 있습니다. 이것은 바보입니다.


유망한 대답 : "슬레이브 서버 인 경우 가장 좋은 해결책은 실제로 데이터베이스를 한쪽으로 옮기고 마스터에서 새 스냅 샷을 설치하는 것입니다." 불행히도 프로덕션 24x7에는 25 개의 데이터베이스에 My20,000과 Mynom이 혼합 된 20,000 개의 테이블이 있습니다. 복제를 다시 시작하기 전에 모든 기능을 종료하고 새로운 전체 복제를 수행하는 데 시간이 오래 걸립니다.
IcarusNM

4
이제이 8 코어 머신을 무의미한 레이스에서 164 기가의 데이터를 생성하고 삭제했습니다. 내가 듣고있는 유일한 대안은이 노예의 모든 것을 핵으로하고 처음부터 다시 시작하는 것입니다. 두 파일에서 하나의 숫자를 효과적으로 변경합니다. 확실히 팁이있는 InnoDB 엔지니어가 있습니다. 누구든지 Emacs에서 ib_logfile0을 열고 16 진수로 마법 번호를 찾은 후 방금 변경 한 적이 있습니까?
IcarusNM

여기 몇 가지 방법에 대한 훌륭한 기사가 있습니다. Percona는 확실히 MySQL의 권위입니다. percona.com/blog/2013/09/11/…
jbrahy

답변:


10

이것은 매우 드문 상황이었습니다. InnoDB "로그 시퀀스 번호가 미래에 있습니다!"로 다시는 끝나지 않기를 바랍니다. 오류. 내 세부 사항으로 인해 서버 데이터를 다시 작성 / 복원하는 것이 최후의 수단이었습니다. 그 아이디어를 돕는 데 도움이되는 몇 가지 요령이 있었지만 결국이 바보 같은 게임을하기 위해 Perl 스크립트를 계속 개선하고 가능한 한 많은 시간당 공연을하기로 결정했습니다. 도대체 좋은 시스템 스트레스 테스트입니다.

기억하십시오 : 목표는 ib_logfile0ib_logfile1 헤더에 저장되는 단일 카운터 ( "로그 시퀀스 번호")를 늘리는 것 입니다. 이것은 InnoDB를 위조하여 명백한 시간 왜곡을 무시하고 생명을 얻는 것입니다. 그러나 아무도 그 번호를 편집하는 방법을 모른다. 또는 그들이 알면 아무도 말하지 않습니다.

여기 내 최종 제품이 있습니다. YMMV이지만 mysql의 REPEAT 함수를 사용하여 내부적으로 데이터를 생성하는 것이 매우 효율적입니다.

 #!/usr/bin/perl
 use DBI;
 $table = shift || die;
 $dbh = DBI->connect("DBI:mysql:junk:host=localhost", "user", "pass"); #Edit "junk" (DB name), user, and pass to suit.
 $dbh->do("DROP TABLE IF EXISTS $table");
 $dbh->do("CREATE TABLE $table (str TEXT) ENGINE=INNODB");
 $sth = $dbh->prepare("INSERT INTO $table (str) VALUES (REPEAT(?,1000000))");
 foreach (1..50) {
    $sth->execute('0123456789');   # 10 MB
 }
 $dbh->do("DELETE FROM $table");

내 제안 레시피 :

  1. '정크'데이터베이스 작성
  2. 위의 perl 스크립트를 junk.pl 로 저장하십시오 .
  3. 데이터베이스 서버만큼 많은 CPU 코어를 시작하려면 junk.pl data1junk.pl data2junk.pl data3 등을 한 번에 모두 실행하십시오 . 여러 쉘을 열고 Bash 루프에서 각 실행을 래핑하십시오 while true; do date; junk.pl dataX; done.

아마도 다른 루프에서 LSN이 성장하는 것을 지켜보십시오.

 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 3871092821
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 124 4209892586
 silly# echo "SHOW INNODB STATUS \G" | mysql -p'xxxxxx' | grep '^Log seq'
 Log sequence number 125 85212387

큰 숫자는 부호없는 32 비트 INT이며 4GB로 줄 바꿈하여 매번 작은 숫자를 증가시킵니다. 이 경우 위의 값은 124에서 125로 롤백되었습니다. 목표는 mysqld.log에 숨겨져 처음에는이 우스운 솔루션에 대한 인터넷 검색을 보냈습니다. 당신이 그 결승선을 건너면 바로 그거야! 뿔을 날려! 색종이를 풀어주세요!

사이드 바 : mysqld 5.0 w / REPEAT에서 흥미로운 버그가 발견되었습니다. 20MB로 가면 내부 카운터가 뒤집어지고 ~ 96KB로 롤오버됩니다. 경고 나 오류가 없습니다. 나는 그것을 추적하는 데 시간을 낭비하지 않았습니다. 10MB는 잘 작동합니다. 다른 제한에 도달하면 불평 할 수 있습니다. 다양한 innodb 버퍼가 기본값보다 증가했습니다. 맛볼 계절. 항상 그렇듯이 mysqld.log를 한 창에서 봅니다.



고마워요 조나스; 그 흥미 롭군요. 위의 방법을 고수 할 수 있다고 생각합니다. 그는 아마 위험하지 않을 mysqld 실행에 대해 gdb를 사용하는 것을 보여줍니다. 그러나 좋은 정보도 있습니다.
IcarusNM

이상한 이유로 MariaDB를 사용하면 '작은 숫자 [공백] 큰 숫자'로그 시퀀스 번호를 얻지 못하지만 '큰 숫자'만 얻으므로 슬프게도이 방법이 효과가 없었습니다. 글쎄, 물론, 로그가 업데이트됩니다. 정지 시점을 모르겠습니다!
Gwyneth Llewelyn 10

5

세 가지 옵션이 있습니다.

옵션 01 : 마스터에서 슬레이브로의 rsync 수행 (마스터에서 다운 타임)

  • 01 단계 : reset master;마스터에서 실행 (Zaps Binary Logs)
  • 02 단계 : service mysql stop마스터
  • 단계 03 : service mysql stop노예에
  • 04 단계 : 마스터에서 슬레이브로 rsync / var / lib / mysql
  • 5 단계 : service mysql start마스터
  • 06 단계 : 마스터의 첫 번째 이진 로그를 로그로 사용하여 복제를 시작합니다. 해당 로그의 파일 크기를 복제 시작 위치로 사용하십시오.
  • 07 단계 : service mysql stop --skip-slave-start노예에서
  • 08 단계 : CHANGE MASTER TO 명령을 실행하여 06 단계에서 확인 된 로그 및 위치에서 복제를 설정하십시오.
  • 9 단계 : start slave;슬레이브에서 실행 하고 복제를 따라 잡기

옵션 02 : 마스터에서 슬레이브로의 rsync 수행 (마스터에서 최소 다운 타임)

  • 01 단계 : reset master;마스터에서 실행 (Zaps Binary Logs)
  • 02 단계 : service mysql stop노예에서
  • 03 단계 : 마스터에서 슬레이브로 rsync / var / lib / mysql
  • 04 단계 : 두 개의 연속 된 rsync가 동일한 시간이 걸릴 때까지 03 단계를 반복합니다.
  • 5 단계 : service mysql stop마스터
  • 06 단계 : 마스터에서 슬레이브로 rsync / var / lib / mysql
  • 07 단계 : service mysql start마스터
  • 08 단계 : 마스터에서 첫 번째 이진 로그를 로그로 사용하여 복제를 시작합니다. 해당 로그의 파일 크기를 복제 시작 위치로 사용하십시오.
  • 단계 09 : service mysql stop --skip-slave-start노예에
  • 10 단계 : CHANGE MASTER TO 명령을 실행하여 08 단계에서 확인 된 로그 및 위치에서 복제를 설정하십시오.
  • 11 단계 : start slave;슬레이브에서 실행 하고 복제를 따라 잡기

옵션 03 : XtraBackup 사용

이 소프트웨어 도구는 실행중인 마스터의 눈에 잘 띄지 않는 복사본을 만들뿐만 아니라 해당 ib_log 파일도 만듭니다. 복제를 설정해야합니다

이 주제에 앞서 StackExchange에 게시했습니다.

나는 고용주의 웹 호스팅 회사를 위해 이런 일들을 여러 번 해냈습니다. 한 고객은 3.7TB로 이동했으며 약 16 시간이 걸렸습니다. 64GB는 매우 작습니다.


OPTION 02 Step 05에서는 마스터를 시작하라고 말합니다. 언제 중지 되었습니까? 라이브 마스터의 Rsync는 우스운 일입니다. 나는 감동. 운 좋게도 innodb_file_per_table을 사용하고 있습니다. 그러나 결국에는 총알을 물고 복제를 시작하기 전에 하나의 최종 rsync가 실행될 수있을만큼 마스터를 중지해야합니다. 그것은 내가 의지 할 수있는 가능성이지만, 이것은 매우 활발한 DBMS입니다. 내 정보는 XtraBackup을 살펴 보겠습니다.
IcarusNM

@IcarusNM : 아, 오타. 나는 그것을 고쳤다. 감사합니다 !!!
RolandoMySQLDBA

옵션 02는 여전히 일부 작업을 사용할 수 있습니다. 예를 들어 1 단계 전에 2 단계를 수행해야합니다. 어딘가에 RESET SLAVE가 필요할 수 있습니다. 4 단계에서 오타 그리고 5 단계에서 "첫 번째 이진 로그"라고 말하지만 실제로는 "단일"또는 "마지막"이진 로그를 의미합니다. 그리고 파일 크기가 아닌 로그 위치를 확인하려면 mysqlbinlog를 사용해야합니다. 그리고 당신이 어떤 시점에서 마스터를 멈추지 않으면이 모든 것이 여전히 작동하지 않습니다. 재 동기화가 완료되면 로그 위치 / 시간을 기준으로하는 것이 가장 위험합니다.
IcarusNM

지난 4 년간 TeraByte 범위의 데이터를 보유한 DB 호스팅 클라이언트에서 OPTION 2를 해왔습니다. 실행중인 서버에 대해 매번 작동합니다. 당신이 할 수있는 유일한 실수는 노예입니다. 이 실수는 복제가 올바르게 설정되었는지 여부에 있습니다. 또한 RESET SLAVE특히 많은 GB의 릴레이 로그를 쌓은 경우에 유용합니다. rsync 프로세스와 복제 재 구축 후에는 CHANGE MASTER TO 명령이 릴레이 로그도 지워진다는 것을 기억하십시오.
RolandoMySQLDBA

음 ... 이상하다. xtrabackup을 사용하여 슬레이브를 설정했지만 (항상)이 로그 오류가 발생합니다 (percona mysql 5.5.x) ...이 슬레이브에 문제가있는 것 같아서 다시해야합니다.
harald

2

분할 된 테이블에서 작동하는이 문제를 해결하는 더 멋진 방법이 있다는 것을 알았습니다. 몇 년 전부터 파티션을 삭제해야했고 2014 년에 파티션을 추가해야했습니다. 거의 모든 파티션이이 오류와 이전 파티션을보고합니다. 매우 심한 충돌.

따라서 오래된 값을 버리고 MAXVALUE 파티션 (마지막 파티션)의 REORGANIZE를 사용하는 동안 괜찮은 새 파일이 생성되므로 경고 메시지가 점점 줄어 듭니다. 그 동안 로그 시퀀스 카운터를 늘리는 데 도움이되므로 가짜 데이터를 삽입 할 필요가 없습니다. 마스터 서버 btw 에서이 문제가 발생했습니다 ...

그래서 이건:

ALTER TABLE Events DROP PARTITION p1530 , p1535 , p1540 , p1545 , 
p1550, p1555 , p1560 , p1565 , p1570 , p1575 , p1580 , p1585 , p1590 , 
p1595 , p1600 , p1605 , p1610 , p1615 , p1620 , p1625 , p1630 , p1635 , 
p1640 , p1645 , p1650 , p1655 , p1660 , p1665 , p1670 , p1675 , p1680 , 
p1685 , p1690 , p1695 , p1700 , p1705 , p1710 , p1715 , p1720 , p1725 , 
p1730 , p1735 , p1740 , p1745 , p1750 , p1755 , p1760 , p1765 , p1770 , 
p1775 , p1780 , p1785 , p1790 , p1795 , p1800 , p1805 , p1810 , p1815 , 
p1820 , p1825 , p1830 , p1835 , p1840;

이:

ALTER table Events REORGANIZE PARTITION p3000 INTO (
PARTITION p3500 VALUES LESS THAN (TO_DAYS('2013-01-01')),
PARTITION p3510 VALUES LESS THAN (TO_DAYS('2013-01-04')),
PARTITION p3520 VALUES LESS THAN (TO_DAYS('2013-01-07')),
PARTITION p3530 VALUES LESS THAN (TO_DAYS('2013-01-10'))
...
PARTITION p4740 VALUES LESS THAN (TO_DAYS('2014-01-08')),
PARTITION p9000 VALUES LESS THAN MAXVALUE)

이렇게하면 변경 사항에서 각 파티션을 효과적으로 삭제하고 거기에 있던 내용의 임시 사본으로 다시 만들 수 있습니다. 원하는 경우 테이블 당이 작업을 수행 할 수 있습니다. 내 응용 프로그램에서이를 허용하므로 동기화 된 백업 등에 대해 걱정할 필요가 없습니다.

나는 그 과정에서 모든 파티션을 손도 안 이제 테이블의 나머지 부분에 대한, 이후 일부가되어 그 사람을 위해, 로그 시퀀스 경고와 함께 남아있을 것입니다 깨진 아마이 실행이 재구성 작용에 의해하지만 및 적용 :

ALTER TABLE Events REBUILD PARTITION p0, p1;

또는

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

그래서, 나는 생각했습니다. 일반 바닐라 테이블을 사용 하여이 작업을 수행 할 수 있습니다. 해시로 파티션을 임시로 추가 한 다음 나중에 제거하십시오 (또는 파티션을 유지하는 것이 좋습니다).

그러나 mysql이 아닌 mariadb를 사용하고 있습니다 (XtraDB).

아마도 이것은 누군가를 도울 것입니다. 나는 지금까지 여전히 실행 중입니다. ENGINE을 변경하면 작업이 수행되는 것처럼 보이므로 MyIsam과 InnoDB간에 다시 가져옵니다.

ENGINE을 변경하면 테이블이 innodb에서 사라 지므로 더 이상 문제가되지 않습니다.

ALTER TABLE Events ENGINE=MyISAM;
ALTER TABLE Events ENGINE=InnoDB;

여기서 작동하는 것 같습니다. 파티션 된 테이블에서 몇 가지 사항을 확인할 수 있습니다.

  • ALTER TABLE xyz ENGINE = InnoDB는 Aria (mariadb)보다 두 배 빠르지 만 일반적으로 로그 시퀀스 카운터를 증가시키는 느린 방법
  • ALTER TABLE xyz REBUILD PARTITION ALL은 테이블을 '고정'하여 카운터를 증가시키는 가장 빠른 방법입니다.
  • ALTER TABLE xyz ANALYZE PARTITION ALL은 이전 버전과 느리게 비교되며 확인 된 파티션을 다시 쓰지 않습니다. REBUILD는 임시 테이블 스키마를 다시 작성합니다.

나는 여러 테이블에서 마지막 것들을 사용했습니다. 경고는 파일을 열려고 할 때 발생하며 모든 파티션 정의마다 카운터 문제로 열립니다. 오늘 마지막 테이블에 대한 카운터를 거의 롤오버했습니다. 일단 처리가 완료되면 바이너리 로그를 플러시해야한다고 생각합니다.

업데이트 : 이제이 문제를 해결하기 위해 몇 가지 결론을 내릴 수 있습니다.

  • Aria 형식 (MariaDB)으로 테이블의 파티션을 재구성하여 충돌이 발생했습니다.
  • (나를 위해) 파티션을 재구성하는 것이 시퀀스 카운터를 얻는 데 가장 빠르고 효과적이었습니다. 엔진 변경은 느리고 innodb에 영향을 주려면 두 번 수행해야합니다. innoDB 로의 변경은 MyIsam 또는 Aria에 비해 상당히 느립니다.
  • 5.5가 아닌 MariaDB 5.3으로 업그레이드했으며 (was : 5.2) 정상적으로 작동합니다. 아리아, 5.5의 파티션 (및 확인 된 버그)에 그 조합을 사용하는 데 너무 많은 문제가 있다고 생각합니다.
  • 로그 시퀀스 카운터를 재설정하는 더 좋은 방법이 있어야합니다.

MariaDB에서는 USE INFORMATION_SCHEMA; SELECT CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` REBUILD PARTITION ALL;") AS MySQLCMD AS MySQLCMD FROM TABLES;(source : dba.stackexchange.com/questions/35073/… )를 사용하여 모든 테이블을 빠르게 변경 하고 일련의 명령으로 실행할 파일에 티를 지정할 수 있습니다.
기네스 Llewelyn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.