Đây là một câu trả lời đầy đủ hơn về InnoDB. Đây là một quá trình hơi dài, nhưng có thể đáng để nỗ lực.
Hãy nhớ rằng / var / lib / mysql / ibdata1
là tệp bận rộn nhất trong cơ sở hạ tầng InnoDB. Nó thường chứa sáu loại thông tin:
- Dữ liệu Bảng
- Chỉ mục Bảng
- MVCC (Kiểm soát đồng tiền đa vũ trụ)
Dữ liệu
- Phân đoạn khôi phục
- Hoàn tác không gian
- Siêu dữ liệu bảng (Từ điển dữ liệu)
- Double Write Buffer (ghi nền để tránh phụ thuộc vào bộ nhớ đệm của hệ điều hành)
- Chèn bộ đệm (quản lý các thay đổi đối với các chỉ mục phụ không phải là duy nhất)
- Xem
Trình bày bằng hình ảnh của ibdata1
Kiến trúc InnoDB
Nhiều người tạo nhiều ibdata
các tệp hy vọng hiệu suất và quản lý không gian đĩa tốt hơn, tuy nhiên niềm tin đó là nhầm lẫn.
Tôi có thể chạy OPTIMIZE không BẢNG
?
Rất tiếc, đang chạy BẢNG TỐI ƯU HÓA
chống lại bảng InnoDB được lưu trữ trong tệp không gian bảng được chia sẻ ibdata1
thực hiện hai điều:
- Làm cho dữ liệu và chỉ mục của bảng tiếp giáp bên trong
ibdata1
- Tạo
ibdata1
phát triển bởi vì dữ liệu liền kề và các trang chỉ mục được nối thêm tớiibdata1
Tuy nhiên, bạn có thể tách riêng Dữ liệu Bảng và Chỉ mục Bảng khỏi ibdata1
và quản lý chúng một cách độc lập.
Tôi có thể chạy OPTIMIZE không BẢNG
với innodb_file_per_table
?
Giả sử bạn thêm innodb_file_per_table
tới /etc/my.cnf (my.ini)
. Sau đó, bạn có thể chỉ cần chạy BẢNG TỐI ƯU
trên tất cả các Bảng InnoDB?
Tin tốt :Khi bạn chạy BẢNG TỐI ƯU HÓA
với innodb_file_per_table
được bật, điều này sẽ tạo ra một .ibd
tệp cho bảng đó. Ví dụ:nếu bạn có bảng mydb.mytable
wiha datadir của / var / lib / mysql
, nó sẽ tạo ra như sau:
-
/var/lib/mysql/mydb/mytable.frm
-
/var/lib/mysql/mydb/mytable.ibd
.ibd
sẽ chứa các Trang dữ liệu và Trang chỉ mục cho bảng đó. Tuyệt vời.
Tin xấu :Tất cả những gì bạn đã làm là trích xuất Trang dữ liệu và Trang chỉ mục của mydb.mytable
sống ở ibdata
. Mục nhập từ điển dữ liệu cho mọi bảng, bao gồm mydb.mytable
, vẫn còn trong từ điển dữ liệu (Xem Trình bày bằng hình ảnh của ibdata1
). BẠN KHÔNG THỂ CHỈ MONG MUỐN XÓA ibdata1
TẠI ĐIỂM NÀY !!! Xin lưu ý rằng ibdata1
không hề bị thu hẹp.
Dọn dẹp cơ sở hạ tầng InnoDB
Để thu nhỏ ibdata1
một lần và mãi mãi, bạn phải làm như sau:
-
Dump (ví dụ:với
mysqldump
) tất cả cơ sở dữ liệu thành một.sql
tệp văn bản (SQLData.sql
được sử dụng bên dưới) -
Bỏ tất cả cơ sở dữ liệu (ngoại trừ
mysql
vàinformation_schema
) CAVEAT :Để phòng ngừa, hãy chạy tập lệnh này để hoàn toàn đảm bảo rằng bạn có tất cả các khoản tài trợ của người dùng:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Đăng nhập vào mysql và chạy
SET GLOBAL innodb_fast_shutdown =0;
(Thao tác này sẽ xóa hoàn toàn tất cả các thay đổi giao dịch còn lại khỏiib_logfile0
vàib_logfile1
) -
Tắt MySQL
-
Thêm các dòng sau vào
/etc/my.cnf
(hoặcmy.ini
trên Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Chú thích bên:Dù bạn đặt gì cho
innodb_buffer_pool_size
, đảm bảoinnodb_log_file_size
là 25% củainnodb_buffer_pool_size
.Ngoài ra:
innodb_flush_method =O_DIRECT
không khả dụng trên Windows) -
Xóa
ibdata *
vàib_logfile *
Tùy chọn, bạn có thể xóa tất cả các thư mục trong/ var / lib / mysql
, ngoại trừ/ var / lib / mysql / mysql
. -
Khởi động MySQL (Thao tác này sẽ tạo lại
ibdata1
[10MB theo mặc định] vàib_logfile0
vàib_logfile1
ở 1G mỗi). -
Nhập
SQLData.sql
Bây giờ, ibdata1
sẽ vẫn phát triển nhưng chỉ chứa siêu dữ liệu bảng vì mỗi bảng InnoDB sẽ tồn tại bên ngoài ibdata1
. ibdata1
sẽ không còn chứa dữ liệu InnoDB và chỉ mục cho các bảng khác.
Ví dụ:giả sử bạn có một bảng InnoDB có tên mydb.mytable
. Nếu bạn tìm trong / var / lib / mysql / mydb
, bạn sẽ thấy hai tệp đại diện cho bảng:
-
mytable.frm
(Tiêu đề công cụ lưu trữ) -
mytable.ibd
(Dữ liệu bảng và chỉ mục)
Với innodb_file_per_table
tùy chọn trong /etc/my.cnf
, bạn có thể chạy TỐI ƯU HÓA mydb.mytable
và tệp /var/lib/mysql/mydb/mytable.ibd
sẽ thực sự thu nhỏ lại.
Tôi đã làm điều này nhiều lần trong sự nghiệp của mình với tư cách là một DBA MySQL. Trên thực tế, lần đầu tiên tôi làm điều này, tôi đã thu hẹp 50GB ibdata1
tệp xuống chỉ còn 500MB!
Hãy thử một lần. Nếu bạn có thêm câu hỏi về điều này, chỉ cần hỏi. Hãy tin tôi; điều này sẽ hiệu quả trong ngắn hạn cũng như lâu dài.
CAVEAT
Tại Bước 6, nếu mysql không thể khởi động lại do mysql
giản đồ bắt đầu bị bỏ, hãy xem lại Bước 2. Bạn đã tạo bản sao vật lý của mysql
lược đồ. Bạn có thể khôi phục nó như sau:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Quay lại Bước 6 và tiếp tục
CẬP NHẬT 2013-06-04 11:13 EDT
Về cài đặt innodb_log_file_size tới 25% innodb_buffer_pool_size ở Bước 5, đó là quy tắc chung khá cũ.
Trở lại ngày 03 tháng 7 năm 2006
, Percona đã có một bài viết hay tại sao phải chọn một innodb_log_file_size thích hợp . Sau đó, vào ngày 21 tháng 11 năm 2008
, Percona tiếp tục với một bài viết khác trên cách tính kích thước phù hợp dựa trên khối lượng công việc cao nhất giữ các thay đổi đáng giá trong một giờ
.
Kể từ đó, tôi đã viết các bài đăng trong DBA StackExchange về cách tính kích thước nhật ký và nơi tôi đã tham khảo hai bài báo Percona đó.
-
Ngày 27 tháng 8 năm 2012
: Điều chỉnh phù hợp cho bảng InnoDB 30 GB trên máy chủ có RAM 48 GB -
Ngày 17 tháng 1 năm 2013
: MySQL 5.5 - Innodb - innodb_log_file_size kết hợp với 4GB?
Cá nhân tôi vẫn sẽ sử dụng quy tắc 25% cho thiết lập ban đầu. Sau đó, vì khối lượng công việc có thể được xác định chính xác hơn theo thời gian trong quá trình sản xuất, bạn có thể thay đổi kích thước nhật ký trong một chu kỳ bảo trì chỉ trong vài phút.