Thứ hai, 20/04/2015 | 00:00 GMT+7

Cách chuẩn bị cho việc nâng cấp MySQL 5.7 của bạn

MySQL 5.7 là thành phần phát hành mới nhất của database nguồn mở phổ biến. Nó cung cấp các tính năng khả năng mở rộng mới mà bạn sẽ mong muốn thực hiện thay đổi.

Một bài báo từ Group MySQL tại Oracle

Để làm nổi bật một trong những thay đổi, khả năng mở rộng đã được cải thiện rất nhiều. Ở cấp độ cao, MySQL 5.7 quy mô tuyến tính trên các server 48 lõi. Ở cấp thấp, MySQL 5.7 cũng hoạt động hiệu quả trên server DigitalOcean 512 MB (điều không thể xảy ra nếu không có thay đổi cấu hình trong MySQL 5.6).

Hiệu suất cao nhất mới cho server MySQL là hơn 640K truy vấn mỗi giây và API memcached, nói trực tiếp với công cụ lưu trữ InnoDB, có khả năng duy trì hơn 1,1 triệu yêu cầu mỗi giây .

Hiệu suất MySQL 5.7 sử dụng API Memcached NoSQL

Tuy nhiên, trước khi vội vàng chạy mysql_upgrade , bạn nên đảm bảo mình đã chuẩn bị. Hướng dẫn này có thể giúp bạn làm điều đó.

Các thay đổi về tính toàn vẹn của dữ liệu, với các ví dụ

Một thay đổi lớn trong MySQL 5.7 là tính toàn vẹn của dữ liệu đã được cải thiện để phù hợp hơn với những gì mà các nhà phát triển và DBA kỳ cựu mong đợi. Trước đây, MySQL sẽ điều chỉnh các giá trị không chính xác thành giá trị chính xác gần nhất có thể, nhưng dưới các giá trị mặc định mới, thay vào đó nó sẽ trả về một lỗi.

Dưới đây là năm ví dụ về các truy vấn sẽ yêu cầu sửa đổi để hoạt động trong MySQL 5.7. Ứng dụng của bạn có sử dụng bất kỳ hành vi nào trong số này không?

1) Chèn giá trị âm vào cột không dấu

Tạo bảng có cột không dấu:

CREATE TABLE test (    id int unsigned   ); 

Chèn một giá trị âm.

Hành vi trước đây:

INSERT INTO test VALUES (-1); Query OK, 1 row affected, 1 warning (0.01 sec) 

MySQL 5.7:

INSERT INTO test VALUES (-1);   ERROR 1264 (22003): Out of range value for column 'a' at row 1 
CREATE TABLE test2 (    id int unsigned   ); 

Cố gắng chia cho không.

Hành vi trước đây:

INSERT INTO test2 VALUES (0/0);   Query OK, 1 row affected (0.01 sec) 

MySQL 5.7:

INSERT INTO test2 VALUES (0/0);   ERROR 1365 (22012): Division by 0 

3) Chèn chuỗi 20 ký tự vào cột 10 ký tự

Tạo bảng có cột 10 ký tự:

CREATE TABLE test3 (   a varchar(10)   ); 

Cố gắng chèn một chuỗi dài hơn.

Hành vi trước đây:

INSERT INTO test3 VALUES ('abcdefghijklmnopqrstuvwxyz');  Query OK, 1 row affected, 1 warning (0.00 sec) 

MySQL 5.7:

INSERT INTO test3 VALUES ('abcdefghijklmnopqrstuvwxyz');   ERROR 1406 (22001): Data too long for column 'a' at row 1 

4) Chèn ngày không chuẩn vào cột ngày giờ

Tạo bảng với cột ngày giờ:

CREATE TABLE test3 (   a datetime   ); 

Chèn 0000-00-00 00:00:00 .

Hành vi trước đây:

INSERT INTO test3 VALUES ('0000-00-00 00:00:00');   Query OK, 1 row affected, 1 warning (0.00 sec) 

MySQL 5.7:

INSERT INTO test3 VALUES ('0000-00-00 00:00:00');   ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'a' at row 1 

5) Sử dụng GROUP BY và chọn một cột không rõ ràng

Điều này xảy ra khi mô tả không phải là một phần của GROUP BY và không có hàm tổng hợp (chẳng hạn như MIN hoặc MAX ) được áp dụng cho nó.

Hành vi trước đây:

SELECT id, invoice_id, description FROM invoice_line_items GROUP BY invoice_id;   +----+------------+-------------+   | id | invoice_id | description |   +----+------------+-------------+   | 1 | 1 | New socks             |   | 3 | 2 | Shoes                 |   | 5 | 3 | Tie                   |   +----+------------+-------------+   3 rows in set (0.00 sec) 

MySQL 5.7:

SELECT id, invoice_id, description FROM invoice_line_items GROUP BY invoice_id;   ERROR 1055 (42000): Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'invoice_line_items.description' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 

Hiểu các hành vi do sql_mode đặt

Theo thuật ngữ MySQL, mỗi hành vi được hiển thị trong phần trước đều bị ảnh hưởng bởi thứ được gọi là sql_mode .

Tính năng ra mắt trong MySQL 4.1 (2004), nhưng chưa được biên dịch theo mặc định. MySQL 5.7 có các chế độ sau được bật theo mặc định:

Chế độ STRICT_TRANS_TABLES cũng trở nên nghiêm ngặt hơn và cho phép hành vi được chỉ định trước đó trong các chế độ ERROR_FOR_DIVISION_BY_ZERO , NO_ZERO_DATENO_ZERO_IN_DATE .

Nhấp vào bất kỳ tên chế độ nào trong số này để truy cập hướng dẫn sử dụng MySQL, để tìm hiểu thêm thông tin.

Đề xuất về cách chuyển đổi

Nếu bạn đang sử dụng version Wordpress, Drupal hoặc Magento gần đây thì tin tốt là bạn không cần phải làm gì cả. Các ứng dụng này đã biết về tính năng sql_mode của MySQL và khi kết nối với MySQL sẽ đặt các tùy chọn tương thích với chúng.

Nếu bạn hiện đang xây dựng một ứng dụng mới , thì bạn nên thay đổi cấu hình của server MySQL 5.6 hiện có của bạn để hoạt động với cài đặt sql_mode được vận chuyển trong MySQL 5.7.

Nếu bạn có một ứng dụng hiện có , bạn có thể cần làm việc với các bản cập nhật của bạn dần dần. Những đề xuất này có thể giúp bạn chuyển đổi:

  • Danh sách trắng : Có các phần mới trong ứng dụng của bạn cho phép tùy chọn <tt> sql mode </tt> mặc định mới . Ví dụ: nếu bạn đang xây dựng một tập hợp các công việc cron để xây dựng lại bộ nhớ đệm dữ liệu, những công việc này có thể đặt <tt> chế độ sql </tt> ngay sau khi chúng kết nối với MySQL. Mã ứng dụng hiện có ban đầu có thể ở lại với hành vi không nghiêm ngặt hiện có.
  • Danh sách đen : Khi bạn đã thực hiện được một số bước tiến trong việc chuyển đổi ứng dụng, đã đến lúc đặt <tt> chế độ sql </tt> mới làm mặc định cho server của bạn. Có thể vẫn có các ứng dụng kế thừa hoạt động trước đó bằng cách yêu cầu chúng thay đổi chế độ sql when they connect to MySQL. On an individual statement basis, MySQL also supports the modifier to downgrade errors. For example: IGNORE modifier to downgrade errors. For example: CHÈN BỎ QUA VÀO my_table '
  • Giới thiệu theo giai đoạn : Nếu bạn đang kiểm soát ứng dụng của bạn , bạn có thể triển khai tính năng thay đổi sql_mode trên cơ sở từng user . Một trường hợp sử dụng tốt cho điều này sẽ là cho phép user nội bộ thử nghiệm beta mọi thứ để cho phép chuyển đổi dần dần.

Bước 1 - Tìm các tuyên bố không tương thích tạo ra cảnh báo hoặc lỗi

Trước tiên, hãy xem có bất kỳ truy vấn hiện tại nào của bạn đang tạo ra cảnh báo hoặc lỗi hay không. Điều này rất hữu ích vì hành vi của một số truy vấn đã thay đổi từ cảnh báo trong 5.6 thành lỗi trong 5.7, vì vậy bạn có thể nắm bắt các cảnh báo ngay bây giờ trước khi nâng cấp.

MySQL performance_schema là một tính năng chẩn đoán được bật theo mặc định trên MySQL 5.6 trở lên. Sử dụng performance_schema , có thể viết một truy vấn để trả về tất cả các câu lệnh mà server gặp phải đã tạo ra lỗi hoặc cảnh báo.

Truy vấn MySQL 5.6+ để báo cáo các câu lệnh tạo ra lỗi hoặc cảnh báo:

SELECT  `DIGEST_TEXT` AS `query`, `SCHEMA_NAME` AS `db`, `COUNT_STAR` AS `exec_count`, `SUM_ERRORS` AS `errors`, (ifnull((`SUM_ERRORS` / nullif(`COUNT_STAR`,0)),0) * 100) AS `error_pct`, `SUM_WARNINGS` AS `warnings`, (ifnull((`SUM_WARNINGS` / nullif(`COUNT_STAR`,0)),0) * 100) AS `warning_pct`, `FIRST_SEEN` AS `first_seen`, `LAST_SEEN` AS `last_seen`, `DIGEST` AS `digest` FROM  performance_schema.events_statements_summary_by_digest WHERE ((`SUM_ERRORS` &gt; 0) OR (`SUM_WARNINGS` &gt; 0)) ORDER BY  `SUM_ERRORS` DESC,  `SUM_WARNINGS` DESC; 

Truy vấn MySQL 5.6+ để báo cáo các câu lệnh tạo ra lỗi:

SELECT  `DIGEST_TEXT` AS `query`, `SCHEMA_NAME` AS `db`, `COUNT_STAR` AS `exec_count`, `SUM_ERRORS` AS `errors`, (ifnull((`SUM_ERRORS` / nullif(`COUNT_STAR`,0)),0) * 100) AS `error_pct`, `SUM_WARNINGS` AS `warnings`, (ifnull((`SUM_WARNINGS` / nullif(`COUNT_STAR`,0)),0) * 100) AS `warning_pct`, `FIRST_SEEN` AS `first_seen`, `LAST_SEEN` AS `last_seen`, `DIGEST` AS `digest` FROM  performance_schema.events_statements_summary_by_digest WHERE  `SUM_ERRORS` &gt; 0 ORDER BY  `SUM_ERRORS` DESC,  `SUM_WARNINGS` DESC; 

Bước 2 - Làm cho MySQL 5.6 Hành xử giống như MySQL 5.7

Bạn cũng có thể chạy thử với MySQL 5.6 để làm cho nó hoạt động giống như 5.7.

Tác giả, Morgan Tocker từ group MySQL, có sẵn một dự án GitHub với một tệp cấu hình mẫu sẽ cho phép bạn thực hiện điều này. Bằng cách sử dụng các giá trị mặc định sắp tới trong MySQL 5.6, bạn có thể loại bỏ khả năng ứng dụng của bạn phụ thuộc vào hành vi ít nghiêm ngặt hơn.

Tệp khá ngắn, vì vậy ta cũng đưa nó vào đây:

# This makes a MySQL 5.6 server behave similar to the new defaults # in MySQL 5.7  [mysqld]  # MySQL 5.7 enables more SQL modes by default, but also # merges ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE, NO_ZERO_IN_DATE # into the definition of STRICT_TRANS_TABLES. # Context: http://dev.mysql.com/worklog/task/?id=7467  sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE"  # The optimizer changes the default from 10 dives to 200 dives by default # Context: http://mysqlserverteam.com/you-asked-for-it-new-default-for-eq_range_index_dive_limit/  eq_range_index_dive_limit=200  # MySQL 5.7 contains a new internal server logging API. # The setting log_warnings is deprecated in 5.7.2 in favour of log_error_verbosity. # *But* the default fo log_warnings also changes to 2 as well:  log_warnings=2  # MySQL 5.7.7 changes a number of replication defaults # Binary logging is still disabled, but will default to ROW when enabled.  binlog_format=ROW sync_binlog=1 slave_net_timeout=60  # InnoDB defaults to the new Dynamic Row format with Barracuda file format. # large_prefix is also enabled, which allows for longer index values.  innodb_strict_mode=1 innodb_file_format=Barracuda innodb_large_prefix=1 innodb_purge_threads=4 # coming in 5.7.8 innodb_checksum_algorithm=crc32  # In MySQL 5.7 only 20% of the pool will be dumped,  # But 5.6 does not support this option  innodb_buffer_pool_dump_at_shutdown=1 innodb_buffer_pool_load_at_startup=1  # These two options had different names in previous versions # (binlogging_impossible_mode,simplified_binlog_gtid_recovery) # This config file targets 5.6.23+, but includes the 'loose' modifier to not fail # prior versions.  loose-binlog_error_action=ABORT_SERVER loose-binlog_gtid_recovery_simplified=1  # 5.7 enable additional P_S consumers by default # This one is supported in 5.6 as well. performance-schema-consumer-events_statements_history=ON  

(Tùy chọn) Bước 3 - Thay đổi sql_mode trên cơ sở mỗi phiên

Đôi khi bạn muốn kiểm tra hoặc nâng cấp server của bạn theo từng giai đoạn. Thay vì thay đổi file cấu hình toàn server của bạn cho MySQL để sử dụng các chế độ SQL mới, bạn cũng có thể thay đổi chúng trên cơ sở mỗi phiên. Đây là một ví dụ:

CREATE TABLE sql_mode_test (a int); 

Không có chế độ SQL nào được đặt:

set sql_mode = ''; INSERT INTO sql_mode_test (a) VALUES (0/0); Query OK, 1 row affected (0.01 sec) 

Đặt chế độ SQL chặt chẽ hơn:

set sql_mode = 'STRICT_TRANS_TABLES'; INSERT INTO sql_mode_test (a) VALUES (0/0); ERROR 1365 (22012): Division by 0 

Sẵn sàng nâng cấp

Đến đây, bạn nên tự tin rằng bạn đã chuẩn bị nâng cấp lên MySQL 5.7. Làm theo cùng với hướng dẫn nâng cấp chính thức của MySQL để lật lựa chọn .

Kết luận

MySQL 5.7 có một bước tiến lớn trong việc cải thiện cấu hình mặc định và tính toàn vẹn dữ liệu cho các ứng dụng hiện đại. Ta hy vọng bài viết này sẽ giúp bạn chuyển đổi suôn sẻ!

Để biết tổng quan về tất cả các thay đổi trong 5.7 (cho đến nay), hãy xem các bài đăng trên blog của Group Server MySQL:


Tags:

Các tin liên quan

Cách sử dụng MySQL hoặc MariaDB với Ứng dụng Django của bạn trên Ubuntu 14.04
2015-03-24
Cách sử dụng MySQL với ứng dụng Ruby on Rails của bạn trên Ubuntu 14.04
2015-03-18
Cách sử dụng MySQL với ứng dụng Ruby on Rails của bạn trên CentOS 7
2015-03-17
Cách đo hiệu suất truy vấn MySQL với mysqlslap
2014-10-02
Cách di chuyển database MySQL sang server mới trên Ubuntu 14.04
2014-05-22
Cách tối ưu hóa hiệu suất WordPress với MySQL Replication trên Ubuntu 14.04
2014-05-21
Cách sử dụng profile truy vấn MySQL
2014-04-07
Mở rộng quy mô Ruby on Rails: Thiết lập server MySQL chuyên dụng (phần 2)
2014-02-27
Cách sử dụng HAProxy để thiết lập cân bằng tải MySQL
2013-12-02
Cách sử dụng HAProxy để thiết lập cân bằng tải MySQL
2013-12-02