Có thể làm sạch một công cụ lưu trữ innodb mysql để nó không lưu trữ dữ liệu từ các bảng đã xóa?
Hay tôi phải xây dựng lại một cơ sở dữ liệu mới mỗi lần?
Có thể làm sạch một công cụ lưu trữ innodb mysql để nó không lưu trữ dữ liệu từ các bảng đã xóa?
Hay tôi phải xây dựng lại một cơ sở dữ liệu mới mỗi lần?
Câu trả lời:
Đây là một câu trả lời đầy đủ hơn liên quan đến InnoDB. Đó là một chút của một quá trình 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:
Pictorial Representation of ibdata1
Nhiều người tạo ra nhiều ibdata
tệp với hy vọng quản lý và hiệu suất không gian đĩa tốt hơn, tuy nhiên niềm tin đó bị nhầm lẫn.
OPTIMIZE TABLE
khôngThật không may, chạy OPTIMIZE TABLE
với bảng InnoDB được lưu trữ trong tệp không gian bảng chia sẻ ibdata1
có hai điều:
ibdata1
ibdata1
tăng trưởng vì dữ liệu và chỉ số trang liền kề được nối 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.
OPTIMIZE TABLE
với innodb_file_per_table
?Giả sử bạn đã thêm innodb_file_per_table
vào /etc/my.cnf (my.ini)
. Bạn có thể chạy OPTIMIZE TABLE
trên tất cả các Bảng InnoDB không?
Tin tốt : Khi bạn chạy OPTIMIZE TABLE
với innodb_file_per_table
kích hoạ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 với một mydb.mytable
datadir của /var/lib/mysql
nó, nó sẽ tạo ra các mục sau:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
Các .ibd
sẽ chứa các trang dữ liệu và Trang Index cho bảng đó. Tuyệt quá.
Tin xấu : Tất cả những gì bạn đã làm là trích xuất các Trang dữ liệu và Trang chỉ mục mydb.mytable
từ khi 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 phần Đại diện hình ảnh của ibdata1 ). BẠN KHÔNG THỂ CHỈ CẦN XÓA ibdata1
ĐƠN GIẢN TẠI ĐIỂM NÀY !!! Xin lưu ý rằng ibdata1
đã không thu hẹp chút nào.
Để thu nhỏ ibdata1
một lần và mãi mãi, bạn phải làm như sau:
Kết xuất (ví dụ: với mysqldump
) tất cả các cơ sở dữ liệu vào một .sql
tệp văn bản ( SQLData.sql
được sử dụng bên dưới)
Bỏ tất cả các cơ sở dữ liệu (ngoại trừ mysql
và information_schema
) CAVEAT : Để phòng ngừa, vui lòng chạy tập lệnh này để đảm bảo chắc chắn rằng bạn có tất cả các khoản trợ cấp 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;
(Điều này sẽ xóa hoàn toàn tất cả các thay đổi giao dịch còn lại từ ib_logfile0
và ib_logfile1
)
Tắt máy MySQL
Thêm các dòng sau vào /etc/my.cnf
(hoặc my.ini
trên Windows)
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
(Sidenote: Bất kể thiết lập của bạn là gì innodb_buffer_pool_size
, hãy đảm bảo innodb_log_file_size
là 25% innodb_buffer_pool_size
.
Ngoài ra: innodb_flush_method=O_DIRECT
không có sẵn 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
.
Bắt đầu MySQL (Điều này sẽ tạo lại ibdata1
[10MB theo mặc định] ib_logfile0
và ib_logfile1
ở mức 1G mỗi cái).
Nhập khẩu SQLData.sql
Bây giờ, ibdata1
vẫn sẽ 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 và chỉ mục của InnoDB cho các bảng khác.
Ví dụ: giả sử bạn có bảng InnoDB được đặt tên mydb.mytable
. Nếu bạn nhìn vào /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
(Bảng dữ liệu và chỉ mục)Với innodb_file_per_table
tùy chọn trong /etc/my.cnf
, bạn có thể chạy OPTIMIZE TABLE mydb.mytable
và tệp /var/lib/mysql/mydb/mytable.ibd
sẽ thực sự co lại.
Tôi đã làm điều này nhiều lần trong sự nghiệp là một DBA của MySQL. Trên thực tế, lần đầu tiên tôi làm điều này, tôi đã thu nhỏ một tệp 50 GB ibdata1
xuống chỉ còn 500 MB!
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. Tin tôi đi; điều này sẽ làm việc trong thời gian ngắn cũng như trên đường dài.
Ở Bước 6, nếu mysql không thể khởi động lại do mysql
lược đồ bắt đầu bị hủy, hãy nhìn 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 trở lại Bước 6 và tiếp tục
Liên quan đến việc đặt innodb_log_file_size thành 25% innodb_buffer_pool_size trong Bước 5, quy tắc chăn đó là trường học khá cũ.
Quay lại July 03, 2006
, Percona đã có một bài viết hay tại sao để chọn một innodb_log_file_size thích hợp . Sau đó, Nov 21, 2008
Percona tiếp tục với một bài viết khác về 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ữ cho giá trị thay đổi trong một giờ .
Kể từ khi tôi viết bài đăng trong DBA StackExchange về việc tính toán kích thước nhật ký và nơi tôi đã tham chiếu hai bài báo Percona đó.
Aug 27, 2012
: Điều chỉnh thích hợp cho bảng InnoDB 30 GB trên máy chủ có RAM 48 GBJan 17, 2013
: MySQL 5.5 - Innodb - innodb_log_file_size cao hơn 4GB kết hợp?Cá nhân, tôi vẫn sẽ sử dụng quy tắc 25% cho thiết lập ban đầu. Sau đó, khi 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 sản xuất, bạn có thể thay đổi kích thước các bản ghi trong một chu kỳ bảo trì chỉ trong vài phút.
innodb_open_tables
nếu cần thiết. Mặc định là 300.
Công cụ InnoDB không lưu trữ dữ liệu đã xóa. Khi bạn chèn và xóa các hàng, không gian chưa sử dụng sẽ được phân bổ trong các tệp lưu trữ InnoDB. Theo thời gian, không gian tổng thể sẽ không giảm, nhưng theo thời gian, không gian 'bị xóa và giải phóng' sẽ được máy chủ DB sử dụng lại tự động.
Bạn có thể điều chỉnh và quản lý thêm không gian được sử dụng bởi động cơ thông qua việc tái lập thủ công các bảng. Để thực hiện việc này, kết xuất dữ liệu trong các bảng bị ảnh hưởng bằng mysqldump, thả các bảng, khởi động lại dịch vụ mysql và sau đó tạo lại các bảng từ các tệp kết xuất.