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/ibdata1là 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 ibdatatệ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 TABLEkhôngThật không may, chạy OPTIMIZE TABLEvới bảng InnoDB được lưu trữ trong tệp không gian bảng chia sẻ ibdata1có hai điều:
ibdata1ibdata1tăng trưởng vì dữ liệu và chỉ số trang liền kề được nối tớiibdata1Tuy nhiên, bạn có thể tách riêng Dữ liệu Bảng và Chỉ mục Bảng khỏi ibdata1và quản lý chúng một cách độc lập.
OPTIMIZE TABLEvới innodb_file_per_table?Giả sử bạn đã thêm innodb_file_per_tablevào /etc/my.cnf (my.ini). Bạn có thể chạy OPTIMIZE TABLEtrên tất cả các Bảng InnoDB không?
Tin tốt : Khi bạn chạy OPTIMIZE TABLEvới innodb_file_per_tablekích hoạt, điều này sẽ tạo ra một .ibdtệp cho bảng đó. Ví dụ: nếu bạn có bảng với một mydb.mytabledatadir của /var/lib/mysqlnó, nó sẽ tạo ra các mục sau:
/var/lib/mysql/mydb/mytable.frm/var/lib/mysql/mydb/mytable.ibdCác .ibdsẽ 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.mytabletừ 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ỏ ibdata1mộ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 .sqltệ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ừ mysqlvà 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_logfile0và ib_logfile1)
Tắt máy MySQL
Thêm các dòng sau vào /etc/my.cnf(hoặc my.initrê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_sizelà 25% innodb_buffer_pool_size.
Ngoài ra: innodb_flush_method=O_DIRECTkhô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_logfile0và ib_logfile1ở mức 1G mỗi cái).
Nhập khẩu SQLData.sql
Bây giờ, ibdata1vẫ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. ibdata1sẽ 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_tabletùy chọn trong /etc/my.cnf, bạn có thể chạy OPTIMIZE TABLE mydb.mytablevà tệp /var/lib/mysql/mydb/mytable.ibdsẽ 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 mysqllượ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 mysqllượ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, 2008Percona 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_tablesnế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.