Chapter 6 MySQL Compliance Framework

Table of Contents

6.1 MySQL Administration Standard Rules
6.2 MySQL Performance Standard Rules
6.3 MySQL Replication Standard Rules
6.4 MySQL Schema Standard Rules
6.5 MySQL Security Standard Rules

For more information on the Oracle Enterprise Manager's Compliance Framework, see Oracle Enterprise Manager Cloud Control Compliance Management.

This chapter documents the following MySQL Compliance Standards:

6.1 MySQL Administration Standard Rules

The following are the MySQL Administration Standard compliance rules:

Binary Log Debug Information Disabled

Description The binary log captures DML, DDL, and security changes that occur and stores these changes in a binary format. The binary log enables point-in-time recovery, preventing data loss during a disaster recovery situation. It also enables you to review all alterations made to your database. The binlog_rows_query_log_events system variable affects row-based logging only. When enabled, it causes a MySQL 5.6.2 or later server to write informational log events such as row query log events into its binary log. This information can be used for debugging and related purposes; such as obtaining the original query issued on the master when it cannot be reconstructed from the row updates. These events are normally ignored by MySQL 5.6.2 and later programs reading the binary log and so cause no issues when replicating or restoring from backup. This is not true for a mysqld or mysqlbinlog from MySQL 5.6.1 or earlier: When the older version of the program reading the log encounters an informational log event, it fails, and stops reading at that point. To make the binary log readable by slave replication MySQL servers and other readers (for example, mysqlbinlog) from a MySQL 5.6.1 or earlier distribution, binlog_rows_query_log_events must be disabled during logging.

Severity MinorWarning

Advice Investigate whether writing informational log events such as row query log events into your binary log is appropriate for your environment (i.e. whether all the servers and other log readers such as mysqlbinlog that will read your logs are MySQL 5.6.2 and later). If so, turn this feature on to capture extra information in your logs. You can dynamically set the value of the binlog_rows_query_log_events system variable to 'ON', but be sure to put the new value in the [mysqld] section of your my.cnf/my.ini file so it remains in effect when you restart the server.

Binary Logging Is Limited

Description The binary log captures DML, DDL, and security changes that occur and stores these changes in a binary format. The binary log enables point-in-time recovery, preventing data loss during a disaster recovery situation. It also enables you to review all alterations made to your database. Binary logging can be limited to specific databases with the --binlog-do-db and the --binlog-ignore-db options. However, if these options are used, your point-in-time recovery options are limited accordingly, along with your ability to review alterations made to your system.

Severity MinorWarning

Advice Review the --binlog-do-db and the --binlog-ignore-db settings in your my.cnf/my.ini file to be sure you are capturing updates to all important databases. They are currently set as follows on server : --binlog-do-db : %binlog_do_db% --binlog-ignore-db : %binlog_ignore_db%

Binary Logging Not Enabled

Description The binary log captures DML, DDL, and security changes that occur and stores these changes in a binary format. The binary log enables point-in-time recovery, preventing data loss during a disaster recovery situation. It also enables you to review all alterations made to your database.

Severity MinorWarning

Advice Enable binary logging for point-in-time recovery by setting the log-bin configuration variable in the [mysqld] section of your my.cnf/my.ini file.

Binary Logging Not Synchronized To Disk At Each Write

Description By default, the binary log contents are not synchronized to disk. If the server host machine or operating system crash, there is a chance that the latest events in the binary log are not persisted on disk. You can alter this behavior using the sync_binlog server variable. If the value of this variable is greater than 0, the MySQL server synchronizes its binary log to disk (using fdatasync()) after sync_binlog commit groups are written to the binary log. The default value of sync_binlog is 0, which does no synchronizing to disk - in this case, the server relies on the operating system to flush the binary log's contents from time to time as for any other file. A value of 1 is the safest choice because in the event of a crash you lose at most one commit group from the binary log. However, it is also the slowest choice (unless the disk has a battery-backed cache, which makes synchronization very fast).

Severity MinorWarning

Advice Set sync_binlog = 1 within the [mysqld] section of your my.cnf/my.ini file to ensure the greatest safety for recovering from hardware, OS, and MySQL server crashes.

Binary Logs Automatically Removed Too Quickly

Description The binary log captures DML, DDL, and security changes that occur and stores these changes in a binary format. The binary log enables point-in-time recovery, preventing data loss during a disaster recovery situation. It is used on master replication servers as a record of the statements to be sent to slave servers. It also enables you to review all alterations made to your database. However, the number of log files and the space they use can grow rapidly, especially on a busy server, so it is important to remove these files on a regular basis when they are no longer needed, as long as appropriate backups have been made. The expire_logs_days parameter enables automatic binary log removal.

Severity MinorWarning

Advice Investigate why binary logs are automatically removed every %expire_logs_days% days. This may be an appropriate setting for your environment, but is unusually low, so be sure that your backup plan and execution is sufficient to support your disaster recovery scenarios. If necessary, increase the setting of expire_logs_days to a value that ensures safe and secure operations in your environment while also minimizing disk usage, and be sure that the binary logs go at least as far back as your last full backup. Be sure to also update the value of expire_logs_days in your my.cnf/my.ini file so it is set properly when the server is restarted.

Database May Not Be Portable Due To Identifier Case Sensitivity

Description The case sensitivity of the underlying operating system determines the case sensitivity of database and table names. If you are using MySQL on only one platform, you don't normally have to worry about this. However, depending on how you have configured your server you may encounter difficulties if you want to transfer tables between platforms that differ in filesystem case sensitivity.

Severity MinorWarning

Advice Set lower_case_table_names=1 in your my.cnf/my.ini file and restart your MySQL server. Note that if you plan to set the lower_case_table_names system variable to 1 on Unix, you must first convert your old database and table names to lowercase before restarting mysqld with the new variable setting.

Event Scheduler Disabled

Description The Event Scheduler is a very useful feature when enabled. It is a framework for executing SQL commands at specific times or at regular intervals. Conceptually, it is similar to the idea of the Unix crontab (also known as a "cron job") or the Windows Task Scheduler. The basics of its architecture are simple. An event is a stored routine with a starting date and time, and a recurring tag. Once defined and activated, it will run when requested. Unlike triggers, events are not linked to specific table operations, but to dates and times. Using the event scheduler, the database administrator can perform recurring events with minimal hassle. Common uses are the cleanup of obsolete data, the creation of summary tables for statistics, and monitoring of server performance and usage.

Severity MinorWarning

Advice Enable the Event Scheduler and use it to automate recurring events. Add the line event_scheduler=1 to the [mysqld] section of your my.cnf/my.ini file so the variable is set properly when the server is restarted.

General Query Log Enabled

Description The general query log is a general record of what mysqld is doing. The server writes information to this log when clients connect or disconnect, and it logs each SQL statement received from clients. The general query log can be very useful when you suspect an error in a client and want to know exactly what the client sent to mysqld. However, the general query log should not be enabled in production environments because: It adds overhead to the server; It logs statements in the order they were received, not the order they were executed, so it is not reliable for backup/recovery; It grows fast and can use a lot of disk space. You should use the binary log instead.

Severity MinorWarning

Advice Disable the general query log: Remove the log option from your my.cnf/my.ini file, or remove the --log option from the script that starts your MySQL server.

In-Memory Temporary Table Size Limited By Maximum Heap Table Size

Description If the space required to build a temporary table exceeds either tmp_table_size or max_heap_table_size , MySQL creates a disk-based table in the server's tmpdir directory. For performance reasons it is ideal to have most temporary tables created in memory, leaving exceedingly large temporary tables to be created on disk. Many DBAs configure tmp_table_size appropriately, but forget that max_heap_table_size also plays a role.

Severity MinorWarning

Advice Consider setting max_heap_table_size to be equal to or larger than tmp_table_size . The variable tmp_table_size is currently set to %tmp_table_size% and max_heap_table_size is set to %max_heap_table_size% .

InnoDB Strict Mode Is Off

Description To guard against ignored typos and syntax errors in SQL, or other unintended consequences of various combinations of operational modes and SQL commands, InnoDB provides a "strict mode" of operations. In this mode, InnoDB will raise error conditions in certain cases, rather than issue a warning and process the specified command (perhaps with some unintended defaults). This is analogous to MySQL's sql_mode, which controls what SQL syntax MySQL will accept, and determines whether it will silently ignore errors, or validate input syntax and data values. Using the new clauses and settings for ROW_FORMAT and KEY_BLOCK_SIZE on CREATE TABLE and ALTER TABLE commands and the CREATE INDEX command can be confusing when not running in strict mode. Unless you run in strict mode, InnoDB will ignore certain syntax errors and will create the table or index, with only a warning in the message log. However if InnoDB strict mode is on, such errors will generate an immediate error and the table or index will not be created, thus saving time by catching the error at the time the command is issued.

Severity MinorWarning

Advice Investigate why the innodb_strict_mode variable is set to OFF. Add innodb_strict_mode=1 to your my.cnf/my.ini file so it is set properly when the server is restarted.

InnoDB System Tablespace Cannot Automatically Expand

Description If the InnoDB system tablespace is not allowed to automatically grow to meet incoming data demands and your application generates more data than there is room for, out-of-space errors will occur and your application may experience problems.

Severity MinorWarning

Advice Configure the InnoDB system tablespace to automatically extend by including the autoextend keyword in your innodb_data_file_path variable in your my.cnf/my.ini file. To help ensure low levels of fragmentation, set the autoextend increment (the amount of space that the InnoDB tablespace will grow) to an amount that is large in size.

InnoDB Transaction Logs Not Sized Correctly

Description To avoid frequent checkpoint activity and reduce overall physical I/O, which can slow down write-heavy systems, the InnoDB transaction logs should be approximately 50-100% of the size of the InnoDB buffer pool, depending on the size of the buffer pool.

Severity MinorWarning

Advice Increase the size of your InnoDB transaction logs. Note, however, that larger transaction logs can mean increased crash recovery times, and more intense checkpointing periods, as more data must be flushed from the buffer pool and logs to the tablespace datafiles. With this in mind, the maximum recommended size is 1 GB per log file. To change the size of your log files, make a clean shutdown of MySQL, alter the value of innodb_log_file_size accordingly within your my.cnf/my.ini file, move the current ib_logfile* files from the data directory to another location, and restart MySQL so the new log files can be created automatically.

Warnings Not Being Logged

Description Error conditions encountered by a MySQL server are always logged in the error log, but warning conditions are only logged if log_warnings is set to a value greater than 0. If warnings are not logged you will not get valuable information about aborted connections and various other communication errors. This is especially important if you use replication so you get more information about what is happening, such as messages about network failures and reconnections.

Severity MinorWarning

Advice Investigate why log_warnings is set to 0. Unless there are clear and compelling reasons not to log warnings, set log_warnings to a value greater than 0. However, when choosing a value for log_warnings, please be aware of Bug #42851 and Bug #46265 . When using binary logging with certain statements, it is possible that setting log_warnings = 2 can flood the error log with warnings about those statements. In those cases, check whether you can use Row Based Logging, as that format is always safe.

6.2 MySQL Performance Standard Rules

The following are the MySQL Performance Standard compliance rules:

InnoDB Flush Method May Not Be Optimal

Description Different values for innodb_flush_method can have a marked effect on InnoDB performance. In some versions of GNU/Linux and Unix, flushing files to disk by invoking fsync() (which InnoDB uses by default) or other similar methods, can be surprisingly slow. If you are dissatisfied with database write performance, you might try setting the innodb_flush_method parameter to O_DIRECT or O_DSYNC.

Severity MinorWarning

Advice Review your setting of the innodb_flush_method variable based on your application, operating system, and storage environment. It is currently set to %flush_method% . The default ( fdatasync ) may be best. O_DIRECT can be good for I/O, especially within "local filesystems", as it also avoids doublewrite buffering. However, O_DIRECT is bad for network attached storage such as SAN/NFS. O_DSYNC can cause extra overhead above the default of fdatasync and there have been problems with it on many varieties of Unix. However, at least one user has reported that using O_DSYNC on NetBSD makes a huge difference.

InnoDB Log Buffer Flushed To Disk After Each Transaction

Description By default, InnoDB's log buffer is written out to the log file at each transaction commit and a flush-to-disk operation is performed on the log file, which enforces ACID compliance. In the event of a crash, if you can afford to lose a second's worth of transactions, you can achieve better performance by setting innodb_flush_log_at_trx_commit to either 0 or 2. If you set the value to 2, then only an operating system crash or a power outage can erase the last second of transactions. This can be very useful on slave servers, where the loss of a second's worth of data can be recovered from the master server if needed.

Severity MinorWarning

Advice Set innodb_flush_log_at_trx_commit=2 in your my.cnf/my.ini file and restart your MySQL server. WARNING: A value of 1 is required for ACID compliance. If you set the value to 2, then an operating system crash or a power outage may erase the last second of transactions. This may not be critical for your application or environment, though, especially if this is a slave server and the loss of a second's worth of data can be recovered from the master.

6.3 MySQL Replication Standard Rules

The following are the MySQL Replication Standard compliance rules:

Binary Log Checksums Disabled

Description Binary logs written and read by the MySQL Server are now crash-safe, because only complete events (or transactions) are logged or read back. By default, the server logs the length of the event as well as the event itself and uses this information to verify that the event was written correctly. You can also cause the server to write checksums for the events using CRC32 checksums by setting the binlog_checksum system variable, to add an extra level of safety to the logs and the replication process. To cause the server to read checksums from the binary log, use the master_verify_checksum system variable. The slave_sql_verify_checksum system variable causes the slave SQL thread to read checksums from the relay log.

Severity MinorWarning

Advice Investigate why binlog_checksum is set to %binlog_checksum%. Turn on checksums by issuing a SET GLOBAL binlog_checksum = CRC32 statement. Add binlog_checksum = CRC32 to your my.cnf/my.ini file to be sure checksums are enabled the next time the server is started.

Binary Log Row Based Images Excessive

Description As of MySQL Server 5.6, row-based replication now supports row image control. By logging only those columns required for uniquely identifying and executing changes on each row (as opposed to all columns) for each row change, it is possible to save disk space, network resources, and memory usage. You can determine whether full or minimal rows are logged by setting the binlog_row_image server system variable to one of the values minimal (log required columns only), full (log all columns), or noblob (log all columns except for unneeded BLOB or TEXT columns).

Severity MinorWarning

Advice Investigate why binlog_row_image is set to %binlog_row_image%. Log only those columns required for uniquely identifying and executing changes on each row by issuing a SET GLOBAL binlog_row_image = minimal . Add binlog_row_image = minimal to your my.cnf/my.ini file to be sure the new setting is in effect the next time the server is started.

Master Not Verifying Checksums When Reading From Binary Log

Description Binary logs written and read by the MySQL Server are now crash-safe, because only complete events (or transactions) are logged or read back. By default, the server logs the length of the event as well as the event itself and uses this information to verify that the event was written correctly. You can also cause the server to write checksums for the events using CRC32 checksums by setting the binlog_checksum system variable, to add an extra level of safety to the logs and the replication process. To cause the server to read checksums from the binary log, use the master_verify_checksum system variable. The slave_sql_verify_checksum system variable causes the slave SQL thread to read checksums from the relay log.

Severity MinorWarning

Advice Investigate why master_verify_checksum is set to %verify_checksum%. Turn on server verification of checksums by issuing a SET GLOBAL master_verify_checksum = ON statement. Add master_verify_checksum = ON to your my.cnf/my.ini file to be sure server checksum verification is enabled the next time the server is started. However, keep in mind that this will add overhead on the master, as the master will need to read the binary log event and verify that the checksum for the event on disk matches what it has in memory. You may want to measure your database performance on a test system before and after making this change to be sure the overhead is acceptable before deploying the change in production.

Slave Detection Of Network Outages Too High

Description Slaves must deal with network connectivity outages that affect the ability of the slave to get the latest data from the master, and hence cause replication to fall behind. However, the slave notices the network outage only after receiving no data from the master for slave_net_timeout seconds . You may want to decrease slave_net_timeout so the outages -- and associated connection retries -- are detected and resolved faster. The default for this parameter is 3600 seconds (1 hour), which is too high for many environments.

Severity MinorWarning

Advice Set slave_net_timeout=60 (or whatever value is reasonable to detect network connectivity outages in your environment) in the [mysqld] section of your my.cnf/my.ini file. The current value of slave_net_timeout is %net_timeout%.

Slave Not Configured As Read Only

Description Arbitrary or unintended updates to a slave may break replication or cause a slave to be inconsistent with respect to its master. Making a slave read_only can be useful to ensure that a slave accepts updates only from its master server and not from clients; it minimizes the possibility of unintended updates.

Severity MinorWarning

Advice Set read_only=1 in your my.cnf/my.ini file to ensure that a slave accepts updates only from its master server and not from clients, and restart your MySQL server.

Slave Not Verifying Checksums When Reading From Relay Log

Description Binary logs written and read by the MySQL Server are now crash-safe, because only complete events (or transactions) are logged or read back. By default, the server logs the length of the event as well as the event itself and uses this information to verify that the event was written correctly. You can also cause the server to write checksums for the events using CRC32 checksums by setting the binlog_checksum system variable, to add an extra level of safety to the logs and the replication process. To cause the server to read checksums from the binary log, use the master_verify_checksum system variable. The slave_sql_verify_checksum system variable causes the slave SQL thread to read checksums from the relay log.

Severity MinorWarning

Advice Investigate why slave_sql_verify_checksum is set to %sql_verify_checksum%. Turn on slave verification of checksums by issuing a SET GLOBAL slave_sql_verify_checksum = ON statement. Add slave_sql_verify_checksum = ON to your my.cnf/my.ini file to be sure slave checksum verification is enabled the next time the server is started.

Slave SQL Processing Not Multi-Threaded

Description As of MySQL Server version 5.6, replication now supports parallel execution of transactions with multi-threading on the slave. When parallel execution is enabled, the slave SQL thread acts as the coordinator for a number of slave worker threads as determined by the value of the slave_parallel_workers server system variable. Note that the current implementation of multi-threading on the slave assumes that data and updates are partitioned on a per-database basis, and that updates within a given database occur in the same relative order as they do on the master. However, it is not necessary to coordinate transactions between different databases. Transactions can then also be distributed per database, which means that a worker thread on the slave can process successive transactions on a given database without waiting for updates to other databases to complete. Also note that since transactions on different databases can occur in a different order on the slave than on the master, simply checking for the most recently executed transaction is not a guarantee that all previous transactions on the master have been executed on the slave. This has implications for logging and recovery when using a multi-threaded slave. However, as of MySQL Server 5.7.5, you can ensure that the order in which transactions were committed to the binary log on the master is preserved on the slave using the slave_preserve_commit_order option variable: MySQL Manual: Replication Slave Options and Variables . Finally, note that beginning with MySQL Server 5.7.2, there is also support for intra-schema parallelization (LOGICAL_CLOCK): MySQL Manual: Replication Slave Options and Variables .

Severity MinorWarning

Advice Investigate why slave_parallel_workers is set to %parallel_workers%. Turn on parallel execution of transactions on a slave by issuing a SET GLOBAL slave_parallel_workers = n statement, where n depends on your specific environment. Add slave_parallel_workers = n to your my.cnf/my.ini file to be sure parallel execution of transactions is enabled the next time the server is started.

6.4 MySQL Schema Standard Rules

The following are the MySQL Schema Standard compliance rules:

Server-Enforced Data Integrity Checking Disabled

Description SQL Modes define what SQL syntax MySQL should support and what kind of data validation checks it should perform. If no SQL modes are enabled this means there is no form of server-enforced data integrity, which means incoming data that is invalid will not be rejected by the server, but instead will be changed to conform to the target column's default datatype. Note that any client can change its own session SQL mode value at any time.

Severity MinorWarning

Advice Ensure that the sql_mode variable contains one of the following in order to obtain the highest level of data integrity: TRADITIONAL, STRICT_TRANS_TABLES, or STRICT_ALL_TABLES . After setting sql_mode to the desired value in your my.cnf/my.ini file, restart your MySQL server.

Server-Enforced Data Integrity Checking Not Strict

Description SQL Modes define what SQL syntax MySQL should support and what kind of data validation checks it should perform. There are many possible options that can be used in conjunction with each other to specify varying degrees of syntax and data validation checks the MySQL server will perform. However, to ensure the highest level of confidence for data integrity, at least one of the following should be included in the list: TRADITIONAL, STRICT_TRANS_TABLES, or STRICT_ALL_TABLES . Note that any client can change its own session SQL mode value at any time.

Severity MinorWarning

Advice Ensure that the sql_mode variable contains one of the following in order to obtain the highest level of data integrity: TRADITIONAL, STRICT_TRANS_TABLES, or STRICT_ALL_TABLES . It is currently set to '%sql_mode%'. After setting sql_mode to the desired value in your my.cnf/my.ini file, restart your MySQL server.

6.5 MySQL Security Standard Rules

The following are the MySQL Security Standard compliance rules:

Audit Log Accounts Excluded

Description The Enterprise Audit Log Plugin is Filtering Events By Account Origin

Severity Warning

Advice When using the options audit_log_include_accounts or audit_log_exclude_accounts, the plug-in may not be logging all events which may be required for later analysis. Consider whether the filtering of events by account is required, and remove the configuration values for audit_log_exclude_accounts or audit_log_include_accounts if not.

Audit Log Policy Not ALL

Description The Enterprise Audit Log Plugin is Filtering Events By Event Status

Severity Warning

Advice When using these options the plug-in may not be logging all events which may be required for later analysis. Consider whether the filtering of events by status is required, and remove the configuration values for audit_log_connection_policy or audit_log_statement_policy if not.

Firewall Disabled

Description MySQL Enterprise Firewall can be in one of two global modes once installed, enabled or disabled.

Severity Warning

Advice To enable or disable the firewall, set the mysql_firewall_mode system variable. By default, this variable is enabled when the firewall is installed. To control the initial firewall state explicitly, you can set the variable at server startup.

LOCAL Option Of LOAD DATA Statement Is Enabled

Description The LOAD DATA statement can load a file that is located on the server host, or it can load a file that is located on the client host when the LOCAL keyword is specified. There are two potential security issues with supporting the LOCAL version of LOAD DATA statements: The transfer of the file from the client host to the server host is initiated by the MySQL server. In theory, a patched server could be built that would tell the client program to transfer a file of the server's choosing rather than the file named by the client in the LOAD DATA statement. Such a server could access any file on the client host to which the client user has read access. In a Web environment where the clients are connecting from a separate web server, a user could use LOAD DATA LOCAL to read any files that the web server process has read access to (assuming that a user could run any statement against the SQL server). In this environment, the client with respect to the MySQL server actually is the web server, not the remote program being run by the user who connects to the web server.

Severity Warning

Advice Start the MySQL Server with the --local-infile option disabled ( --local-infile=0 ), or add " local-infile = 0 " to your my.cnf/my.ini file.

Symlinks Are Enabled

Description You can move tables and databases from the database directory to other locations and replace them with symbolic links to the new locations. You might want to do this, for example, to move a database to a file system with more free space or to increase the speed of your system by spreading your tables to different disks. However, symlinks can compromise security. This is especially important if you run mysqld as root, because anyone who has write access to the server's data directory could then delete any file in the system!

Severity Warning

Advice Disable the use of symlinks by starting MySQL with the --skip-symbolic-links option or adding skip-symbolic-links to your my.cnf/my.ini file and restarting the server.