Còn cách nào tốt hơn để thoát khỏi log nhật ký MySQL InnoDB trong tương lai không?


16

Tôi đã gặp lỗi InnoDB này trong MySQL 5.0. Mysqld đã bị dừng hoàn toàn, nhưng sau đó tôi đã mất ib_logfile0 & ib_logfile1. Bây giờ sau khi khởi động sạch, InnoDB đã thực hiện "phục hồi sự cố". Tôi đã trải qua innodb_force_recovery = 4 doanh nghiệp, sửa chữa một bảng MyISAM treo và bây giờ nhân rộng đã sẵn sàng để đi, ngoài việc này. Số lượng lớn được ủy thác:

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.

Đây là trên một máy chủ nô lệ. Các lỗi trên xuất hiện bởi hàng trăm. Tôi đã tìm thấy câu trả lời này: "chèn và xóa dữ liệu trị giá 64 GB, để số thứ tự nhật ký trở nên đủ lớn".

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

Con số 64GB ma thuật đó đến từ 4GB * 16 trong đó bản ghi "số chính" của anh chàng đó cần tăng từ 0 lên 15. Của tôi sẽ tăng từ 70 lên 111 = 164 GB. Điều này sẽ mất 5 ngày. Tôi sẽ tiếp tục tăng tốc kịch bản của mình và chạy song song để tăng tốc độ này. Trong khi đó, tôi hy vọng người khác có câu trả lời tốt hơn. Điều này thật ngốc nghếch.


Một câu trả lời đầy hứa hẹn: "Nếu đó là một máy chủ nô lệ, giải pháp tốt nhất thực sự sẽ là chuyển cơ sở dữ liệu sang một bên và cài đặt một ảnh chụp nhanh mới từ chủ." Thật không may, có 20.000 bảng trên 25 cơ sở dữ liệu, kết hợp MyISAM và InnoDB, trong sản xuất 24x7. Sẽ mất quá nhiều thời gian để tắt tất cả và thực hiện sao chép hoàn toàn mới trước khi bắt đầu sao chép lại.
IcarusNM

4
Bây giờ tôi có máy 8 lõi này trên đầu gối trong một cuộc đua vô nghĩa để tạo và xóa 164 hợp đồng dữ liệu. Cách thay thế duy nhất tôi nghe được là nuke tất cả mọi thứ trên nô lệ này và bắt đầu lại từ đầu. Tất cả để thay đổi một cách hiệu quả một số trong hai tập tin. Chắc chắn có một số kỹ sư InnoDB ngoài kia với một mẹo chuyên nghiệp. Có ai đã từng mở ib_logfile0 trong Emacs, tìm thấy số ma thuật trong hex và chỉ cần thay đổi nó?
IcarusNM

Đây là một bài viết tuyệt vời về một vài cách để làm điều đó. Percona chắc chắn là người có thẩm quyền trên MySQL. percona.com/blog/2013/09/11/ từ
jbrahy

Câu trả lời:


10

Đây là một tình huống khá hiếm. Tôi hy vọng sẽ không bao giờ kết thúc ở đó một lần nữa, với "số thứ tự nhật ký của InnoDB trong tương lai!" lỗi. Do các chi tiết cụ thể của tôi, việc xây dựng lại / khôi phục dữ liệu máy chủ của tôi là giải pháp cuối cùng. Một số mánh khóe giúp đỡ đó là những ý tưởng hay, nhưng cuối cùng, tôi quyết định chỉ tiếp tục cải thiện kịch bản Perl của mình để chơi trò chơi ngớ ngẩn này và lướt qua nhiều hợp đồng / giờ nhất có thể. Cái quái gì thế, đó là một bài kiểm tra căng thẳng hệ thống tốt.

Hãy nhớ rằng: mục tiêu là tăng một bộ đếm ("số thứ tự nhật ký") được lưu trữ ở đâu đó trong các tiêu đề của ib_logfile0ib_logfile1 . Điều này là để giả mạo InnoDB để nó sẽ bỏ qua một sự chênh lệch thời gian rõ ràng và tiếp tục với cuộc sống. Nhưng không ai biết cách chỉnh sửa con số đó. Hoặc nếu họ biết, không ai nói chuyện.

Đây là sản phẩm cuối cùng của tôi. YMMV, nhưng sử dụng chức năng REPEAT của mysql để tạo dữ liệu trong nội bộ có hiệu quả cao.

 #!/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");

Công thức gợi ý của tôi:

  1. Tạo cơ sở dữ liệu 'rác'
  2. Save the script perl trên như junk.pl .
  3. Chạy rác.pl data1rác.pl data2rác.pl data3 , v.v ... tất cả cùng một lúc, để có nhiều lõi CPU như máy chủ cơ sở dữ liệu của bạn bắt đầu. Mở nhiều shell và bọc mỗi lần chạy trong một vòng lặp Bash : while true; do date; junk.pl dataX; done.

Xem LSN của bạn phát triển, có thể trong một vòng lặp khác:

 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

Số lớn là một INT 32 bit không dấu sẽ bao bọc ở mức 4GB, tăng số lượng nhỏ hơn mỗi lần. Trong trường hợp trên, nó chỉ lăn từ 124 đến 125. Mục tiêu của bạn được ẩn trong mysqld.log đã gửi cho bạn Google về giải pháp vô lý này ngay từ đầu. Một khi bạn vượt qua vạch đích, đó là nó! Thổi kèn! Phát hành confetti!

Thanh bên: Điều này đã phát hiện ra một lỗi thú vị trong mysqld 5.0 w / REPEAT: nếu bạn đi đến 20 MB, nó sẽ lật một số bộ đếm nội bộ và cuộn lên tới ~ 96 KB. Không có cảnh báo hoặc lỗi ở bất cứ đâu. Tôi đã không lãng phí thời gian để theo dõi điều đó. 10 MB hoạt động tuyệt vời. Nếu bạn đạt một số giới hạn khác, nó có thể khiếu nại. Tôi có bộ đệm innodb khác nhau tăng từ mặc định. Nêm nếm vừa ăn. Như mọi khi, hãy xem mysqld.log trong một cửa sổ.



Cảm ơn Jonas; Nó thật thú vị. Tôi nghĩ rằng tôi có thể gắn bó với phương pháp của tôi ở trên. Anh ta cho thấy sử dụng gdb chống lại mysqld đang chạy mà tôi có thể sẽ không bao giờ gặp rủi ro. Nhưng thông tin tốt ở đó quá.
IcarusNM

Vì một số lý do kỳ lạ, khi sử dụng MariaDB, tôi không nhận được số thứ tự nhật ký number số nhỏ [không gian] số lớn - nhưng chỉ là 'số lớn', thật đáng buồn là phương pháp này không hiệu quả với tôi. Chà, tất nhiên, nhật ký được cập nhật, tôi chỉ không biết khi nào nên dừng lại!
Gwyneth Llewelyn

5

Bạn có ba (3) tùy chọn:

TÙY CHỌN 01: Thực hiện rsync của Master to Slave (Thời gian ngừng hoạt động trên Master)

  • Bước 01: Chạy reset master;trên bản gốc (Nhật ký nhị phân Zaps)
  • Bước 02: service mysql stopvề chủ
  • Bước 03: service mysql stoptrên nô lệ
  • Bước 04: rsync / var / lib / mysql từ chủ đến nô lệ
  • Bước 05: service mysql startvề chủ
  • Bước 06: Sử dụng nhật ký nhị phân đầu tiên trên bản gốc làm nhật ký để bắt đầu sao chép từ đó. Sử dụng kích thước tệp của nhật ký đó làm vị trí để bắt đầu sao chép từ
  • Bước 07: service mysql stop --skip-slave-starttrên nô lệ
  • Bước 08: Chạy lệnh CHANGE MASTER TO để thiết lập sao chép từ nhật ký và vị trí được xác định từ Bước 06
  • Bước 09: Chạy start slave;trên nô lệ và để nhân rộng bắt kịp

TÙY CHỌN 02: Thực hiện rsync của Master to Slave (Thời gian ngừng hoạt động tối thiểu trên Master)

  • Bước 01: Chạy reset master;trên bản gốc (Nhật ký nhị phân Zaps)
  • Bước 02: service mysql stoptrên nô lệ
  • Bước 03: rsync / var / lib / mysql từ chủ đến nô lệ
  • Bước 04: Lặp lại Bước 03 cho đến khi hai rsyncs liên tiếp mất cùng một lượng thời gian
  • Bước 05: service mysql stopvề chủ
  • Bước 06: rsync / var / lib / mysql từ chủ đến nô lệ
  • Bước 07: service mysql startvề chủ
  • Bước 08: Sử dụng nhật ký nhị phân đầu tiên trên bản gốc làm nhật ký để bắt đầu sao chép từ đó. Sử dụng kích thước tệp của nhật ký đó làm vị trí để bắt đầu sao chép từ
  • Bước 09: service mysql stop --skip-slave-starttrên nô lệ
  • Bước 10: Chạy lệnh CHANGE MASTER TO để thiết lập sao chép từ nhật ký và vị trí được xác định từ Bước 08
  • Bước 11: Chạy start slave;trên nô lệ và để nhân rộng bắt kịp

TÙY CHỌN 03: Sử dụng XtraBackup

Công cụ phần mềm này sẽ không chỉ tạo một bản sao không gây khó chịu cho một bậc thầy đang chạy mà còn tạo ra ib_logfiles tương ứng cho bạn. Bạn sẽ phải thiết lập sao chép

Tôi đã đăng lên StackExchange trước đây về chủ đề này

Tôi đã làm những việc này nhiều lần cho công ty lưu trữ web của chủ nhân. Một khách hàng có 3,7TB để di chuyển và mất khoảng 16 giờ. 64GB là rất nhỏ so với.


Trong TÙY CHỌN 02 Bước 05 bạn nói để bắt đầu làm chủ. Khi nào nó dừng lại? Rsync trên một bậc thầy sống là táo bạo. Tôi rất ấn tượng. Và may mắn là tôi đang sử dụng innodb_file_per_table. Nhưng cuối cùng, bạn phải cắn viên đạn và dừng bản gốc đủ lâu để một rsync cuối cùng chạy trước khi bắt đầu sao chép. Đó là một khả năng tôi có thể dùng đến, nhưng đây là một DBMS rất tích cực. Và tôi sẽ xem XtraBackup để biết thông tin của tôi.
IcarusNM

@IcarusNM: Ah, lỗi đánh máy. Tôi sửa nó rồi. Cảm ơn bạn !!!
RolandoMySQLDBA

TÙY CHỌN 02 có thể vẫn có thể sử dụng một số công việc. Ví dụ: Bạn nên thực hiện bước 2 trước bước 1. Bạn có thể muốn có một RESET SLAVE ở đó ở đâu đó. Nhập Typo ở bước 4. Và bạn nói "nhật ký nhị phân đầu tiên" ở bước 5 nhưng bạn thực sự có nghĩa là nhật ký nhị phân "chỉ" hoặc "cuối cùng". Và bạn nên sử dụng mysqlbinlog để xác định vị trí nhật ký, không phải kích thước tệp. Và tất cả điều này vẫn không hoạt động trừ khi bạn dừng chủ ở một số điểm. Dựa vào vị trí / thời gian đăng nhập khi rsync kết thúc là rủi ro cao nhất.
IcarusNM

Tôi đã thực hiện TÙY CHỌN 2 trong 4 năm qua với các khách hàng DB Hosting có dữ liệu trong Phạm vi TeraByte. Nó hoạt động mỗi lần đối với một máy chủ đang chạy. Sai lầm thực sự duy nhất bạn có thể mắc phải là về nô lệ. Đó là sai lầm trong việc sao chép được thiết lập đúng hay không. Ngoài ra, RESET SLAVErất hữu ích, đặc biệt nếu bạn đã tích lũy nhiều GB nhật ký chuyển tiếp. Sau quá trình rsync và thiết lập lại bản sao, vui lòng nhớ lệnh CHANGE MASTER TO cũng sẽ xóa sạch nhật ký chuyển tiếp cho bạn.
RolandoMySQLDBA

Ừm ... lạ thật. tôi đã thiết lập nô lệ của mình bằng xtrabackup (như mọi khi) và vẫn gặp phải các lỗi đăng nhập này (percona mysql 5.5.x) ... có vẻ như đã xảy ra sự cố với nô lệ này và tôi phải làm lại.
harald

2

Tôi phát hiện ra rằng có lẽ có một cách hay hơn để giải quyết vấn đề này khi làm việc trên các bảng được phân vùng. Tôi cần phải bỏ phân vùng từ một số năm trước và phải thêm một số cho năm 2014. Hầu như tất cả các phân vùng đều báo cáo lỗi này, vì vậy cũng có những phân vùng cũ. Tai nạn rất khó chịu.

Vì vậy, trong khi DROPPING cũ và sử dụng REORGANIZE của phân vùng MAXVALUE (cái cuối cùng), nó sẽ tạo ra các tệp mới ổn, vì vậy tôi nhận được ngày càng ít cảnh báo. Trong lúc này, nó giúp tăng bộ đếm chuỗi nhật ký, vì vậy tôi không cần phải chèn dữ liệu không có thật. Tôi có điều này xảy ra trên một máy chủ chính btw ...

Vậy đây:

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;

Và điều này:

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)

Điều đó sẽ loại bỏ hiệu quả từng phân vùng trong thay đổi và tạo lại nó với một bản sao tạm thời nội dung của những gì có trong đó. Bạn có thể làm điều này trên mỗi bảng nếu bạn muốn, ứng dụng của tôi cho phép điều đó xảy ra, vì vậy không cần phải lo lắng về sao lưu được đồng bộ hóa, v.v.

Bây giờ đối với phần còn lại của bảng, vì tôi chưa chạm vào tất cả các phân vùng trong quy trình, một số sẽ bị bỏ lại với cảnh báo trình tự nhật ký, đối với những cái bị hỏng nhưng được bao phủ bởi hành động sắp xếp lại này, tôi có thể sẽ chạy nó:

ALTER TABLE Events REBUILD PARTITION p0, p1;

hoặc đó

ALTER TABLE Events OPTIMIZE PARTITION p0, p1;

Vì vậy, điều đó khiến tôi suy nghĩ, Bạn có thể làm điều này với các bảng vanilla đơn giản, thêm tạm thời các phân vùng bằng hàm băm và sau đó xóa nó (hoặc giữ chúng, tôi hoàn toàn có thể đề xuất các phân vùng).

Tuy nhiên, tôi đang sử dụng mariadb, không phải mysql (vì vậy XtraDB)

Có lẽ điều này giúp một ai đó. Tôi vẫn đang chạy nó, cho đến nay rất tốt. Thay đổi ĐỘNG CƠ dường như cũng thực hiện công việc, vì vậy tôi mang nó qua lại giữa MyIsam và họ trở lại InnoDB.

Nó khá logic, nếu bạn thay đổi ĐỘNG CƠ, bảng sẽ biến mất khỏi innodb, vì vậy nó sẽ không còn là vấn đề nữa.

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

nó dường như làm việc ở đây Tôi có thể xác nhận một vài điều trên các bảng được phân vùng:

  • ALTER TABLE xyz Engine = InnoDB rất chậm, để Aria (mariadb) nhanh gấp đôi, nhưng nói chung là một cách chậm để tăng bộ đếm trình tự nhật ký
  • ALTER TABLE xyz PHẦN THAM GIA TÁI TẠO TẤT CẢ là cách nhanh nhất để 'sửa chữa' các bảng và giúp tăng bộ đếm
  • ALTER TABLE xyz ANALYZE PHẦN TẤT CẢ bị chậm so với trước đây và không viết lại các phân vùng mà kiểm tra là ok. REBUILD đảm bảo viết lại vào lược đồ bảng tạm thời.

Tôi đã sử dụng những cái cuối cùng trên một số bảng. Các cảnh báo xảy ra khi nó cố mở các tệp và có một định nghĩa cho mọi định nghĩa phân vùng mà nó mở với các vấn đề truy cập. Hầu như lăn qua quầy ngày hôm nay cho các bảng cuối cùng. Tôi nghĩ rằng một khi tất cả đã được xử lý, người ta cần phải xóa các bản ghi nhị phân.

cập nhật : Tôi có thể kết luận một vài điều bây giờ tôi quản lý để giải quyết vấn đề này.

  • Sự cố của tôi là do sắp xếp lại các phân vùng trên một bảng theo định dạng Aria (MariaDB).
  • (đối với tôi) thực hiện việc xây dựng lại các phân vùng hoạt động tốt nhất và nhanh nhất để có được bộ đếm trình tự. Việc thay đổi động cơ chậm và bạn cần thực hiện hai lần để ảnh hưởng đến innodb. việc thay đổi thành innoDB khá chậm so với MyIsam hoặc Aria.
  • Tôi đã nâng cấp lên MariaDB 5.3 và không lên 5.5 (là: 5.2) và nó hoạt động tốt. Tôi nghĩ có quá nhiều vấn đề với aria, các phân vùng trong 5.5 (và các lỗi đã được xác nhận) để sử dụng kết hợp đó.
  • Thực sự nên có một cách tốt hơn để thiết lập lại bộ đếm chuỗi nhật ký.

Trong MariaDB, bạn có thể nhanh chóng thay đổi tất cả các bảng bằng cách sử dụng USE INFORMATION_SCHEMA; SELECT CONCAT("ALTER TABLE `", TABLE_SCHEMA,"`.`", TABLE_NAME, "` REBUILD PARTITION ALL;") AS MySQLCMD AS MySQLCMD FROM TABLES;(nguồn: dba.stackexchange.com/questions/35073/ mẹo ) và chuyển nó thành một tệp để được thực thi dưới dạng một loạt các lệnh.
Gwyneth Llewelyn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.