Tại sao các bảng MySQL bị sập? Làm thế nào để tôi ngăn chặn nó?


9

Tôi là Quản trị viên của một trang Moodle có bảng Người dùng bị hỏng và nó trở nên không sử dụng được.

May mắn thay, một đơn giản REPAIR TABLE mdl_userlàm cho nó hoạt động trở lại. Vấn đề là tôi không biết tại sao nó thực sự bị hỏng và khiến nó không sử dụng được, và tôi muốn chắc chắn rằng tôi sẽ chuẩn bị tốt hơn vào lần tới.

Tôi không phải là một DBA có kinh nghiệm kỹ lưỡng - Tôi chỉ là một nhà phát triển làm rất nhiều thứ, vì vậy hãy đồng ý với tôi.

Tôi chỉ có thể khôi phục bản sao lưu, nhưng tôi đoán có nhiều cách để ngăn chặn sự cố.

Các bảng đó là utf8_general_ci và sử dụng MyISAM.

Tại sao một bảng MySQL sụp đổ? Tôi có thể làm gì để ngăn chặn điều đó xảy ra?

Câu trả lời:


11

Nó khá dễ dàng để một bảng MyISAM bị sập.

Trong tiêu đề của mỗi bảng MyISAM là một bộ đếm theo dõi có bao nhiêu tệp xử lý đang mở đối với bảng.

Nếu bạn khởi động mysql và số trong tiêu đề không khớp với số lượng tệp xử lý thực tế so với, mysqld coi bảng là bị hỏng.

Nếu một đơn giản REPAIR TABLE mdl_userlàm cho nó hoạt động trở lại mỗi lần mà không mất dữ liệu, điều này có thể cho thấy rằng bạn có một trang web bị buôn bán rất cao mà ghi vào mdl_user.

Nếu hàng tá bảng yêu cầu điều này REPAIR TABLE, tôi sẽ chuyển đổi tất cả các bảng thành InnoDB. Tuy nhiên, nếu mdl_userbảng là bảng duy nhất có vấn đề này, có một số thứ bạn có thể làm (ví dụ này, giả sử cơ sở dữ liệu là moodle);

Nếu bạn muốn tất cả các bảng còn lại là MyISAM

BƯỚC 01: Tạo Tập lệnh Bảng sửa chữa

echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql

BƯỚC 02: Khai báo Script Script là tệp khởi động

Thêm phần này vào /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql

BƯỚC 03: Khởi động lại mysql

Mỗi lần khởi động lại của mysql sẽ kích hoạt Script Table Repair

Nếu bạn muốn tất cả các bảng trở thành InnoDB

Chạy mã này để tạo tập lệnh chuyển đổi hàng loạt các bảng MyISAM sang InnoDB và xem nó

MYSQL_USER=root
MYSQL_PASS=password
MYSQL_CONN="-u${MYSQL_USER} -p ${MYSQL_PASS}"
echo "SET SQL_LOG_BIN = 0;" > /root/ConvertMyISAMToInnoDB.sql
mysql ${MYSQL_CONN} -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > /root/ConvertMyISAMToInnoDB.sql
less /root/ConvertMyISAMToInnoDB.sql

Khi bạn hài lòng với nội dung của tập lệnh chuyển đổi, sau đó chạy nó

mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql

CẬP NHẬT 2012/03/15 14:00 EDT

@Kevin , Trong khi sử dụng MyISAM, điều gì xảy ra nếu hết Dung lượng đĩa là vấn đề của bạn?

Đây là một cái gì đó để xem xét: Theo Hướng dẫn nghiên cứu chứng chỉ MySQL 5.0 ,

nhập mô tả hình ảnh ở đây

gạch đầu dòng # 11 nói như sau trên trang 408,409 Mục 29.2:

Nếu bạn hết dung lượng đĩa trong khi thêm hàng vào bảng MyISAM, sẽ không xảy ra lỗi. Máy chủ tạm dừng hoạt động cho đến khi có chỗ trống, và sau đó hoàn thành thao tác.

Khi bạn hết dung lượng đĩa, không chỉ tắt hoặc giết mysql. Số lượng xử lý tệp đang mở trong mọi MyISAM hiện đang sử dụng sẽ không bị xóa. Do đó, bảng MyISAM bị đánh dấu bị lỗi. Nếu bạn có thể giải phóng không gian đĩa trong ổ dữ liệu mà mysqld vẫn đang chạy, mysqld sẽ chạy trên một khi không gian đĩa có sẵn.


Phản ứng tuyệt vời. Không biết bit xử lý tệp và bạn đã giải quyết làm thế nào tôi có thể ngăn chặn (hoặc tự động sửa chữa) trong trường hợp xảy ra sự cố. Bất kỳ đề xuất nào về an toàn nếu trên thực tế trang web ghi rất nhiều vào mdl_user (hoặc bất kỳ bảng nào khác)?
AeroCross 15/03/2016

Bạn nên làm ba việc: 1) tăng RAM, 2) tăng max_connections, 3) chuyển sang InnoDB.
RolandoMySQLDBA

Không có ở đây. Tôi "chạy" mã này ở đâu? Từ một tập tin được tải lên máy chủ hoặc từ một số dòng lệnh?
UncaughtTypeError

0

Tôi cũng quản trị một trang web moodle trên mysql và nguyên nhân phổ biến nhất của tham nhũng bảng đối với chúng tôi là hết dung lượng đĩa.


@RolandoMySQLDBA - yeah, dung lượng ổ đĩa chắc chắn là vấn đề (liên quan đến một số quy trình khác và triết lý quản lý nói chung). Thật không may, chúng ta không thấy vấn đề tự giải quyết khi không gian bị xóa, hoặc nó không tự giải quyết kịp thời. Phản hồi của tôi chỉ là chỉ ra rằng với ví dụ moodle / mysql của chúng tôi, các vấn đề về không gian đĩa có thể gây ra sự cố bảng, bất kể mysql / myisam phải làm gì.
Kevin

-3

Tôi đã tìm thấy một dòng tốt để chuyển đổi tất cả các bảng sang InnoDB:

mysql -u root -p dbName -e "show table status where Engine='MyISAM';" | 
    awk 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}'  | 
    mysql -u root -p dbName

Mã có thể ổn cho điều đó nhưng nó không trả lời câu hỏi phần đầu tiên (Tại sao bảng MySQL bị sập?). Nếu bạn muốn nói rằng nó trả lời phần thứ hai (Làm thế nào để ngăn chặn nó?), Xin vui lòng thêm một số giải thích.
ypercubeᵀᴹ

Ngoài ra thêm chi tiết. Sẽ chạy này chuyển đổi tất cả các bảng trong cơ sở dữ liệu? Hay toàn bộ máy chủ? Điều gì sẽ xảy ra nếu một bảng không chuyển đổi và chúng tôi gặp lỗi? Có thể chúng ta kết thúc với một số bảng được chuyển đổi và một số bảng còn lại trong MyiSAM? Nói chung, DBA nên cân nhắc những điều gì khác trước khi chạy nó?
ypercubeᵀᴹ
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.