MySQL InnoDB 로그에서“미래에”더 나은 방법은 무엇입니까? 복제를 수행 할 수 있습니다. 큰 숫자는

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 일이 소요됩니다. 스크립트 속도를 높이고 속도를 높이기 위해 병렬로 실행합니다. 그 동안 다른 사람이 더 나은 답변을 기대하고 있습니다. 이것은 바보입니다.



답변

이것은 매우 드문 상황이었습니다. 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를 한 창에서 봅니다.


답변

세 가지 옵션이 있습니다.

옵션 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는 매우 작습니다.


답변

분할 된 테이블에서 작동하는이 문제를 해결하는 더 멋진 방법이 있다는 것을 알았습니다. 몇 년 전부터 파티션을 삭제해야했고 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의 파티션 (및 확인 된 버그)에 그 조합을 사용하는 데 너무 많은 문제가 있다고 생각합니다.
  • 로그 시퀀스 카운터를 재설정하는 더 좋은 방법이 있어야합니다.

답변