TechnoBase DBMS | SQL Server | Oracle | PostgreSQL | Unix/Linux
MySQL
MySQL Architecture ---- Storage engines -------- The InnoDB storage engine ------------ InnoDB multi-versioning ------------ The InnoDB buffer pool ---------------- Buffer pool flushing ------------ Tablespaces ---------------- The system tablespace ---------------- File-per-table tablespaces ---------------- General tablespaces ---------------- The temporary tablespace ------------ Redo log and buffer ------------ Undo logs ------------ Doublewrite buffer ------------ Change buffer ------------ Adaptive hash index ------------ Thread concurrency ------------ Background threads ------------ Flushing data from memory ------------ Row formats -------- The Federated storage engine ---- MySQL programs -------- mysqld -------- MySQL client programs ------------ mysql ------------ mysqlcheck -------- Option files ---- Data directory ---- MySQL data dictionary ---- Internal temporary tables ---- Temporary files ---- MySQL server logs -------- Binary log -------- General query log -------- Slow query log Database Objects ---- Databases -------- Information_schema ---- Tables -------- Constraints -------- Table compression -------- Partitioning -------- Online DDL ---- Indexes -------- Full-text indexes ---- Stored objects -------- Views -------- Stored routines -------- Triggers -------- Events -------- Access control for stored programs and views ---- Object names MySQL language ---- Data types ---- Operators ---- Statements -------- Administrative statements -------- Control flow statements -------- DDL statements -------- DML statements -------- Prepared statements ---- Functions ---- User-defined variables Server administration ---- Installing/upgrading MySQL ---- MySQL startup/shutdown ---- Server configuration -------- Server variables -------- Server SQL modes -------- Character set and collation -------- Opening and closing tables ---- Connection management -------- Connection manager threads -------- Host cache -------- Connection character sets and collations ---- MySQL server plugins ---- Monitoring the server -------- Information_schema tables -------- Performance schema ------------ Performance schema tables -------- Sys schema -------- InnoDB monitors -------- Monitoring memory usage Transaction/Query management ---- Transaction handling ---- InnoDB locks ---- Transaction and locking information ---- Semaphores and mutexes ---- Query optimization -------- Buffering -------- Using Explain -------- Query profiling Importing/Exporting data ---- Loading text files -------- Load Data statement ---- Exporting table data Backup/Recovery ---- Backups/Restores -------- mysqldump ---- Troubleshooting/Recovery -------- MySQL startup problems -------- Connection errors -------- Error codes User Management/Security ---- User accounts ---- Privileges -------- Grant tables -------- Roles ---- Authenticating connections -------- Pluggable authentication ---- Encrypted connections ---- Data encryption -------- Encryption functions -------- Tablespace encryption High availability/Scalability ---- Replication -------- Configuring replication ------------ GTID-based replication ------------ Multi-threaded replication ------------ Replication channels ------------ Filtered replication -------- Monitoring replication ------------ Handling errors -------- Stopping/resetting replication ---- Group Replication ---- NDB Cluster -------- NDB Cluster installation -------- Caching of configuration data -------- NDB Cluster management client ---- InnoDB Cluster Tools/Utilities ---- MySQL Workbench ---- MySQL Enterprise monitor ---- MySQL utilities ---- MySQL Shell


MySQL ARCHITECTURE

Storage Engines

Storage engines are MySQL components that handle the SQL operations for different table types. The default engine is InnoDB which is the most general-purpose storage engine and is recommended for tables except for specialized use cases. MySQL Server uses a pluggable storage engine architecture that enables storage engines to be loaded into and unloaded from a running MySQL server.

The SHOW ENGINES statement displays which storage engines a server supports. The value in the Support column indicates whether an engine can be used. A value of YES, NO, or DEFAULT indicates that an engine is available or not or available and currently set as the default.
	SHOW ENGINES;
	SHOW GLOBAL VARIABLES LIKE '%engine%';
		default_storage_engine	- default engine
		default_tmp_storage_engine - default engine for temp tables
Storage engine types InnoDB - supports transactions, row-level locking, and foreign keys MyISAM - no transaction support, table-level locking, more speed CSV - stores data in comma-separated text files MRG_MYISAM - collection of identical MyISAM tables BLACKHOLE - /dev/null storage engine (anything written to it disappears) MEMORY - hash based, stored in memory, useful for temporary tables FEDERATED - accesses data in tables of remote databases rather than in local tables ARCHIVE - used for storing large amounts of data without indexes in a very small footprint PERFORMANCE_SCHEMA - performance schema
The InnoDB storage engine

InnoDB is a general purpose storage engine that is the default unless configured otherwise. InnoDB balances reliability and performance and supports ACID model for transactions, row-level locking and Oracle-style consistent reads, data compression and encryption.

InnoDB page size

The innodb_page_size variable specifies the page size for innoDB tablespaces. This value is set when the instance is created and remains constant afterward. Valid values are 64kB, 32kB, 16kB (default) 8kB and 4kB.
	SHOW GLOBAL STATUS LIKE 'Innodb_page_size';	- default 16kB
The default 16KB page size or larger is appropriate for a wide range of workloads, particularly for queries involving table scans and bulk updates. Smaller page sizes might be more efficient for OLTP workloads involving many small writes, where contention can be an issue when single pages contain many rows. Smaller pages might also be efficient with SSD storage devices which typically use small block sizes. Keeping the InnoDB page size close to the storage device block size minimizes the amount of unchanged data that is rewritten to disk.

InnoDB multi-versioning

InnoDB is a multi-versioned storage engine - it keeps information about old versions of changed rows, to support transactional features such as concurrency and rollback. This information is stored in the tablespace in a data structure called a rollback segment. InnoDB uses the information in the rollback segment to perform the undo operations needed in a rollback and to build earlier versions of a row for a consistent read.

Multiversion concurrency control (MVCC) lets InnoDB transactions with certain isolation levels perform consistent read operations; i.e to query rows being updated by other transactions, and see the values from before those updates occurred. This is a powerful technique to increase concurrency, by allowing queries to proceed without waiting due to locks.

Internally, InnoDB adds three fields to each row stored in the database.
  • A 6-byte DB_TRX_ID field indicates the last transaction that inserted or updated the row.
  • A 7-byte DB_ROLL_PTR field called the roll pointer, pointing to an undo log record written to the rollback segment. If the row was updated, the undo log record contains the information necessary to rebuild the content of the row before it was updated.
  • A 6-byte DB_ROW_ID field contains a row ID that increases monotonically as new rows are inserted. If InnoDB generates a clustered index automatically, the index contains row ID values. Otherwise, the DB_ROW_ID column does not appear in any index.

    MVCC treats secondary indexes differently than clustered indexes. Records in a clustered index are updated in-place, and their hidden system columns point undo log entries from which earlier versions of records can be reconstructed. Unlike clustered index records, secondary index records do not contain hidden system columns nor are they updated in-place.

    The InnoDB buffer pool

    InnoDB maintains a storage area called the buffer pool for caching data and indexes in memory. Ideally, the size of the buffer pool can be set to as large a value as practical (75% of available RAM is a standard), leaving enough memory for other processes on the server to run without excessive paging. The larger the buffer pool, the more InnoDB acts like an in-memory database, reading data from disk once and saving it in memory for subsequent reads. Changes made to data pages that are cached in the buffer pool are written to the data files sometime later, a process known as flushing.

    Using the innodb_buffer_pool_instances option, the buffer pool can be divided into a user-specified number of separate regions, each with its own LRU (Least recently used) list and related data structures to reduce contention during concurrent memory read and write operations. This option only takes effect when innodb_buffer_pool_size is set to 1GB or more. The total size is divided among all the buffer pools.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool%';
    		innodb_buffer_pool_size 	- the size of the buffer pool, making the pool larger can reduce the amount of disk I/O
    		innodb_buffer_pool_instances 	- divides the buffer pool into separate regions to improve concurrency
    
    	SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_pages%';
    		Innodb_buffer_pool_pages_data	- number of pages in the buffer pool containing data (includes both dirty and clean pages). When 
    			using compressed tables, the value may be larger than pages_total
    		Innodb_buffer_pool_pages_dirty	- current number of dirty pages (data changed in memory but not saved to data files)
    		Innodb_buffer_pool_pages_free	- number of free pages
    		Innodb_buffer_pool_pages_misc	- number of pages that are allocated for administrative overhead, such as row locks or the 
    			adaptive hash index
    		Innodb_buffer_pool_pages_total	- total size of the buffer pool in pages
    		
       	SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_read%';		
    		Innodb_buffer_pool_read_requests	- number of logical read requests
    		Innodb_buffer_pool_reads		- number of logical reads that InnoDB couldn't satisfy from the pool, and had to read from disk
    		
    	SHOW GLOBAL STATUS LIKE 'Innodb_buffer_pool_wait_free';	- number of times InnoDB had to wait/flush dirty pages for a clean page to be 
    				available. Should be 0 or low if buffer pool size is adequate
    InnoDB manages the buffer pool as a list, using a variation of the LRU algorithm. When room is needed to add a new page to the pool, InnoDB evicts the least recently used page and adds the new page to the middle of the list. This 'midpoint insertion strategy' treats the list as two sublists - at the head, a sublist of new (or young) pages that were accessed recently and at the tail, a sublist of old pages that were accessed less recently.

    The LRU algorithm operates as follows by default
  • 3/8 of the buffer pool is devoted to the old sublist
  • The midpoint of the list is the boundary where the tail of the new sublist meets the head of the old sublist
  • When InnoDB reads a page (for a query or a read-ahead operation) into the buffer pool, it initially inserts it at the midpoint (the head of the old sublist).
  • Accessing a page in the old sublist makes it young, moving it to the head of the buffer pool (the head of the new sublist). If the page was read in because it was required, the first access occurs immediately and the page is made young. If the page was read in due to read-ahead, the first access does not occur immediately (and might not occur at all before the page is evicted).
  • As the database operates, pages in the buffer pool that are not accessed age by moving toward the tail of the list. Pages in both the new and old sublists age as other pages are made new. Pages in the old sublist also age as pages are inserted at the midpoint. Eventually, a page that remains unused reaches the tail of the old sublist and is evicted

    The insertion point in the LRU list can be controlled using the innodb_old_blocks_pct parameter that controls the percentage of the buffer pool used for the old block sublist. The innodb_old_blocks_time parameter specifies the time in milliseconds a block inserted into the old sublist must stay there after its first access before it can be moved to the new sublist. Values greater than 0 prevent the new sublist from being flooded by table scans
    	SHOW GLOBAL VARIABLES LIKE 'innodb_old_blocks%';
    		innodb_old_blocks_pct	- range 5 to 95, default 37 (3/8 of the pool)
    		innodb_old_blocks_time	- default 1000
    Buffer pool flushing

    InnoDB uses a flush list to track dirty pages in the buffer pool that need to be flushed. This data structure is updated frequently by InnoDB's internal mini-transactions and is protected by its own mutex to allow concurrent access to the buffer pool.

    Buffer pool flushing is performed by page cleaner threads, whose number is controlled by the innodb_page_cleaners variable, which has a default value of 4. If innodb_page_cleaners exceeds the number of buffer pool instances, it is automatically set to the same value as innodb_buffer_pool_instances.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_page_cleaners';
    Buffer pool flushing is initiated when the percentage of dirty pages reaches the low water mark value defined by the innodb_max_dirty_pages_pct_lwm variable. The default is 10% of buffer pool pages and a value of 0 disables this early flushing behaviour.

    The purpose of the innodb_max_dirty_pages_pct_lwm threshold is to control the percentage of dirty pages in the buffer pool and to prevent dirty pages from reaching the threshold defined by the innodb_max_dirty_pages_pct variable, which has a default value of 90. InnoDB aggressively flushes buffer pool pages if the innodb_max_dirty_pages_pct threshold is reached.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_max_dirty_pages_pct%';
    		innodb_max_dirty_pages_pct	- percentage of dirty pages
    		innodb_max_dirty_pages_pct_lwm	- low water mark
    
    	SHOW GLOBAL STATUS LIKE 'innodb_buffer_pool_pages_flushed';	- the number of requests to flush pages from the buffer pool
    Adaptive flushing

    InnoDB uses an adaptive flushing algorithm that tracks the number of dirty pages in the buffer pool and the rate at which redo log records are being generated and dynamically adjusts the number of dirty pages to flush each second, ensuring that flushing activity keeps pace with the current workload. Automatically adjusting the flushing rate helps avoid sudden dips in throughput that can occur when bursts of I/O activity due to flushing affects the I/O capacity available for ordinary read and write activity.

    The innodb_adaptive_flushing_lwm variable defines a low water mark representing percentage of redo log capacity. When that threshold is crossed, adaptive flushing is enabled, even if the innodb_adaptive_flushing variable is disabled.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_adaptive_flushing%';
    		innodb_adaptive_flushing	- ON by default
    		innodb_adaptive_flushing_lwm	- defaults to 10

    Back


    Tablespaces

    The system tablespace

    The system tablespace contains the InnoDB data dictionary (metadata for InnoDB-related objects) and is the storage area for the doublewrite buffer, the change buffer and undo logs.

    The system tablespace is represented by one or more data files. By default, a single system tablespace data file, named ibdata1, is created in the data directory. The innodb_data_file_path variable defines the name, size and attributes of system tablespace data file(s). The default value is ibdata1:12M:autoextend.

    When the autoextend attribute is specified, the data file automatically increases in size by increments as space is required. The innodb_autoextend_increment variable controls the increment size.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_data_%';
    		innodb_data_file_path	- system tablespace data file(s)
    		innodb_data_home_dir	- directory path for the file(s)
    	SHOW GLOBAL VARIABLES LIKE 'innodb_autoextend_increment';	- the increment size (MB) for extending the file(default = 64)
    										
    	SELECT * FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME = 'innodb_system';	- system tablespace metadata
    Once having grown, the ibdata files cannot be shrunk. To reduce the size, the databases need to be dumped and dropped and restored back after deleting the ibdata and ib_log files and restarting the server.

    The InnoDB data dictionary is comprised of internal system tables that contain metadata of objects such as tables, indexes and columns. The metadata is physically located in the InnoDB system tablespace.

    File-per-table tablespaces

    If the innodb_file_per_table option is enabled (by default), each table and its indexes are stored in a separate .ibd data file. Each such .ibd data file represents an individual tablespace. The shared tablespace file ibdata1 is then used to store other internal data - data dictionary (metadata) of InnoDB tables, change buffer, doublewrite buffer, undo logs. Else all tables are all stored together in a system tablespace (ibdata files).

    Tables created in file-per-table tablespaces use the Barracuda file format which enables features such as compressed and dynamic row formats. Each table also has a .FRM file which stores the structure of the table. File-per-table tablespace files are auto-extending regardless of the innodb_autoextend_increment setting. The initial extensions are by small amounts, after which extensions occur in increments of 4MB.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_file_per_table';	- 0 or 1
    		
    	RENAME TABLE db1.tblname TO db2.tblname;	- moves an .ibd file and associated table to another db
    Restoring tables from files

    A table can be restored from its .ibd and .frm files by extracting the structure from the .frm file, creating the table, discarding the tablespace to delete the .ibd file and then importing the required tablespace file.
    	ALTER TABLE tblname DISCARD TABLESPACE;	- delete current .ibd file for a table
    	ALTER TABLE tblname IMPORT TABLESPACE;	- use a new .idb file
    MyISAM tables exist in the form of three files - .FRM (table structure), .MYD (data) and .MYI (indexes). The files can be copied into the /var/lib/mysql/dbname folder to make the table available. REPAIR TABLE repairs a possibly corrupted table. The USE_FRM option is available for use if the .MYI index file is missing or if its header is corrupted. This option tells MySQL not to trust the information in the .MYI file header and to re-create it using information from the .frm file.

    General tablespaces

    A general tablespace is a shared InnoDB tablespace that is created using the CREATE TABLESPACE statement and can be created in the data directory or outside of it.
    	CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
    	CREATE TABLESPACE ts1 ADD DATAFILE '/home/usr/ts1.ibd' Engine=InnoDB;	- creating outside the data directory
    	
    	ALTER TABLESPACE ts1 RENAME TO ts2;
    	DROP TABLESPACE ts1;
    If FILE_BLOCK_SIZE is not specified when creating a general tablespace, FILE_BLOCK_SIZE defaults to innodb_page_size and the tablespace may only contain uncompressed tables.
    	CREATE TABLESPACE ts1 ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB;
    ALTER TABLE ... DISCARD TABLESPACE and ALTER TABLE ...IMPORT TABLESPACE are not supported for tables that belong to a general tablespace.

    Temporary tablespace

    All non-compressed user-created temporary tables and on-disk internal temporary tables are created in a shared temporary tablespace. Compressed temporary tables reside in file-per-table tablespace files created in the temporary file directory, defined by tmpdir.

    The innodb_temp_data_file_path variable defines the relative path, name, size and attributes of temporary tablespace data files. If no value is specified, by default a single auto-extending data file named ibtmp1 is created in the innodb_data_home_dir directory.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_temp_data_file_path'; - temporary tablespace
    The INFORMATION_SCHEMA.FILES provides metadata about the temporary tablespace.
    	SELECT * FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME = 'innodb_temporary'; - temp tablespace metadata
    The INNODB_TEMP_TABLE_INFO table provides info about user-created InnoDB temporary tables that are active (not internal temporary tables). The table is created when first queried, exists only in memory and is not persisted to disk.
    	SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO; - active user-created temp tables
    The disk space occupied by the temporary tablespace data file can be reclaimed by restarting the MySQL server, which removes and recreates the file.


    Redo Log and buffer

    The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions. During normal operations, the redo log encodes requests to change InnoDB table data that result from SQL statements or low-level API calls. Modifications that did not finish updating the data files before an unexpected shutdown are replayed automatically during initialization and before the connections are accepted. By default, the redo log is physically represented on disk as a set of files, named ib_logfile0 and ib_logfile1.

    The redo log buffer is the memory area that holds data to be written to the redo log. The redo log buffer is periodically flushed to the log file on disk. A large redo log buffer enables large transactions to run without the need to write redo log to disk before the transactions commit. Thus, for transactions that update, insert or delete many rows, making the log buffer larger saves disk I/O.

    The redo log files should be sufficiently large, optimally to hold at least an hour's worth of bytes written to the log. When the log file is full, InnoDB must write the modified contents of the buffer pool to disk in a checkpoint and smaller redo log files cause many unnecessary disk writes. The combined size of log files (innodb_log_file_size * innodb_log_files_in_group) cannot exceed 512GB.

    The Log Sequence Number (LSN) is an 8-byte unsigned integer, an arbitrary, ever-increasing value that represents a point in time corresponding to operations recorded in the redo log. This point in time is regardless of transaction boundaries and can fall in the middle of transactions. It is used internally by InnoDB during crash recovery and for managing the buffer pool.

    InnoDB uses fuzzy checkpointing, a technique that flushes small batches of dirty pages from the buffer pool, rather than flushing all dirty pages at once which would disrupt database processing. The checkpoint label written to the log file is a record of the latest changes (represented by an LSN value) that have been successfully written to the data files. During crash recovery all modifications in the log after the checkpoint are applied.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_log%';
    		innodb_log_file_size		- size in bytes of each log file in a log group
    		innodb_log_files_in_group	- number of log files in the log group
    		innodb_log_buffer_size		- size in bytes of the buffer that InnoDB uses to write to the log files on disk (default 16MB)
    
    	SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log%';	
    		innodb_flush_log_at_trx_commit	- controls how the contents of the log buffer are written to the log file
    		innodb_flush_log_at_timeout	- controls redo log flushing frequency (default once per sec)
    
    	SHOW GLOBAL STATUS LIKE 'innodb_log_writes';	- number of physical writes to the log files
    	SHOW GLOBAL STATUS LIKE 'innodb_os_log_written';- number of bytes written to the log files
    	SHOW GLOBAL STATUS LIKE 'innodb_log_waits';	- number of times the log buffer was too small and had to be flushed before continuing

    Back


    Undo logs

    An undo log record contains information about how to undo the change by a transaction to a clustered index record. If another transaction needs to see the original data (as part of a consistent read operation), the unmodified data is retrieved from the undo log records. An undo log is a collection of undo log records associated with a single transaction. Undo logs exist within undo log segments, contained within rollback segments which reside in the system tablespace, global temporary tablespace and undo tablespaces.

    Each undo tablespace and the temporary tablepace individually support a maximum of 128 rollback segments defined by the innodb_rollback_segments variable. The number of data-modifying transactions that a rollback segment supports depends on the number of undo slots in the segment and the number of undo logs required by each transaction. The number of undo slots in a rollback segment (InnoDB page size/16) for the default 16kB page size is 1024.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_rollback_segments';	- maximum 128(default)
    Undo logs that reside in the global temporary tablespace are used for transactions that modify data in user-defined temporary tables. These undo logs are not redo-logged, as they are not required for crash recovery and are used only for rollback while the server is running. This type of undo log benefits performance by avoiding redo logging I/O.

    Purging of undo logs no longer needed for MVCC or rollback is done by one or more background threads (controlled by innodb_purge_threads) running on a periodic schedule. Purge parses and processes undo log pages from the history list.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_purge_threads';
    Doublewrite buffer

    The doublewrite buffer is a storage area located in the system tablespace where InnoDB writes pages that are flushed from the InnoDB buffer pool, before writing to the data file. Only after flushing and writing pages to the doublewrite buffer, does InnoDB write pages to the data file. If there is an OS, storage or mysqld process crash in the middle of a page write, InnoDB can later find a good copy of the page from the doublewrite buffer during crash recovery.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_doublewrite';	- enabled by default
    Although data is always written twice, the doublewrite buffer does not require twice as much I/O overhead or twice as many I/O operations. Data is written to the doublewrite buffer as a large sequential chunk, with a single fsync() call to the OS.

    Doublewrite buffering is enabled by default and can be turned off when top performance is needed rather than concern for data integrity or possible failures.

    Change buffer

    The change buffer is a special data structure that caches changes to secondary index pages when the affected pages are not in the buffer pool. The buffered changes resulting from DML are merged later when the pages are loaded into the buffer pool by other read operations.

    Unlike clustered indexes, secondary indexes are usually non-unique and inserts happen in a relatively random order and deletes and updates may affect pages that are not adjacently located in an index tree. Merging cached changes at a later time, when affected pages are read into the buffer pool by other operations, avoids substantial random access I/O. Periodically, the purge operation that runs when the system is mostly idle writes the updated index pages to disk. The purge operation can write disk blocks for a series of index values more efficiently than if each value were written to disk immediately.

    Change buffer merging may take several hours when there are many affected rows and secondary indexes to update and during this time, disk I/O is increased and can cause a significant slowdown for disk-bound queries. Change buffer merging may also continue to occur after a transaction is committed and even after a server shutdown and restart.

    The change buffer occupies part of the buffer pool in memory and on disk, the change buffer is part of the system tablespace where index changes are buffered when the database server is shut down.

    The extent to which InnoDB performs change buffering can be controlled using the innodb_change_buffering configuration parameter.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_change_buffering';
    			all - buffer inserts, delete-marking operations and purges (default)
    			none - do not buffer any operations
    			inserts - buffer insert operations
    			deletes - buffer delete-marking operations
    			changes - buffer both inserts and delete-marking operations
    			purges - buffer the physical deletion operations that happen in the background
    The innodb_change_buffer_max_size variable permits configuring the maximum size of the change buffer as a percentage of the buffer pool size. The default is set to 25 and the maximum is 50.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_change_buffer_max_size';
    			
    	select name, comment from INFORMATION_SCHEMA.INNODB_METRICS where name like '%ibuf%'\G	- change buffer metrics
    Adaptive hash index

    The adaptive hash index (AHI) lets InnoDB perform more like an in-memory database without sacrificing any transactional features or reliability. This feature is enabled by the innodb_adaptive_hash_index option.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_adaptive_hash_index';	- ON by default
    Based on the observed pattern of searches, MySQL builds a hash index using a prefix of the index key. The prefix of the key can be any length and only some of the values in the B-tree may appear in the hash index. Hash indexes are built on demand for those pages of the index that are often accessed.

    If a table fits almost entirely in main memory, a hash index can speed up queries by enabling direct lookup of any element, turning the index value into a pointer. InnoDB monitors index searches and if it notices that queries could benefit from building a hash index, it does so automatically.

    The adaptive hash index feature is partitioned and partitioning is controlled by the innodb_adaptive_hash_index_parts variable. Each index is bound to a specific partition and each partition is protected by a separate latch.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_adaptive_hash_index_parts';	- default 8, maximum 512
    Access to the adaptive hash index can sometimes become a source of contention under heavy workloads. If there are many threads waiting on RW-latches created in btr0sea.cc, it might be useful to increase the number of partitions or disable adaptive hash indexing.

    Thread concurrency

    InnoDB uses OS threads to process requests from user transactions. In heavy workloads, the number of concurrent threads can be limited by setting the configuration parameter innodb_thread_concurrency. Once the number of executing threads reaches this limit, additional threads sleep for a number of microseconds, set by innodb_thread_sleep_delay, before being placed into the queue.

    The default value of innodb_thread_concurrency is 0 and there is no limit on the number of concurrently executing threads. All threads contend equally to be scheduled and the value of innodb_thread_sleep_delay is ignored.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_thread_concurrency';	- maximum OS threads that can run concurrently inside InnoDB
    	SHOW GLOBAL VARIABLES LIKE 'innodb_thread_sleep_delay';
    The option innodb_adaptive_max_sleep_delay can be set to the highest value to be allowed for innodb_thread_sleep_delay and InnoDB automatically adjusts innodb_thread_sleep_delay up or down depending on the current thread-scheduling activity. This dynamic adjustment helps the thread scheduling mechanism to work smoothly across varying loads.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_adaptive_max_sleep_delay';
    Background threads

    InnoDB uses background threads to service various types of I/O requests. The number of background threads that service read and write I/O on data pages can be configured using the innodb_read_io_threads and innodb_write_io_threads parameters. The default value for these parameters is 4 and permissible values range from 1-64.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_%threads';
    		innodb_read_io_threads		- threads servicing read I/O requests
    		innodb_write_io_threads		- threads servicing write I/O requests
    These configuration options make InnoDB more scalable on high end systems. Each background thread can handle up to 256 pending I/O requests. A major source of background I/O is read-ahead requests. InnoDB tries to balance the load of incoming requests in such way that most background threads share work equally and also attempts to allocate read requests from the same extent to the same thread to increase the chances of coalescing the requests. On high end I/O subsystems, if more than (64 x innodb_read_io_threads) pending read requests are seen in SHOW ENGINE INNODB STATUS output, performance may be improved by increasing the value of innodb_read_io_threads.

    The InnoDB main thread (thread/sql/main) performs various operations in the background including checking free log space - ensure that there is enough reusable space in the redo log files
    doing background drop tables
    enforcing dict cache limit - make room in the table cache by evicting an unused table
    flushing log - sync redo log to disk
    doing insert buffer merge
    making checkpoint - flush dirty pages from buffer pool to disk and record the checkpoint LSN

    Flushing data from memory

    The flushing method used to flush data to data and log files can affect I/O throughput based on hardware configuration and workload. If innodb_flush_method is set to NULL on a Unix system, the fsync option is used by default and on Windows, the async_unbuffered option is used by default.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_flush_method';	- flushing method
    The innodb_flush_method options for Unix systems include:
    fsync - InnoDB uses the fsync() system call to flush both the data and log files. fsync is the default setting
    O_DSYNC - uses O_SYNC to open and flush the log files, and fsync() to flush the data files
    O_DIRECT - uses O_DIRECT to open the data files, and uses fsync() to flush both the data and log files
    O_DIRECT_NO_FSYNC - InnoDB uses O_DIRECT during flushing I/O, but skips the fsync() system call afterward

    The innodb_flush_method options for Windows systems include:
    async_unbuffered - InnoDB uses Windows asynchronous I/O and non-buffered I/O, default on Windows systems
    normal: InnoDB uses simulated asynchronous I/O and buffered I/O
    unbuffered: InnoDB uses simulated asynchronous I/O and non-buffered I/O

    InnoDB I/O capacity

    The innodb_io_capacity variable defines the number of I/O operations per second (IOPS) available to InnoDB background tasks, such as flushing pages from the buffer pool and merging data from the change buffer. If flushing activity falls behind, InnoDB can flush more aggressively at a higher rate of IOPS than defined by innodb_io_capacity up to a maximum defined by the innodb_io_capacity_max variable.

    Although very high values can be specified for innodb_io_capacity, they have little benefit in practice and a value higher than 20000 is generally not recommended. Systems with large write workloads are likely to benefit from a higher setting. Available I/O capacity is distributed equally among buffer pool instances for flushing activities.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_io%';
    		innodb_io_capacity	- default 200
    		innodb_io_capacity_max	- defaults to twice the value of innodb_io_capacity, with a minimum value of 2000

    Row formats

    The row format of a table determines how its rows are physically stored. InnoDB supports four row formats
  • REDUNDANT - provides compatibility with older versions of MySQL
  • COMPACT - reduces row storage space by about 20% compared to the REDUNDANT row format. It is likely to be faster for workloads limited by cache hit rates and disk speed and slower for those limited by CPU speed
  • DYNAMIC - offers the same storage characteristics as COMPACT but adds enhanced storage capabilities for long variable-length columns and supports large index key prefixes
  • COMPRESSED - offers the same storage characteristics and capabilities as DYNAMIC but adds support for table and index data compression

    The innodb_default_row_format option defines the default row format for InnoDB tables and user-created temporary tables, when a ROW_FORMAT option is not specified explicitly or when ROW_FORMAT=DEFAULT is used.
    	SHOW GLOBAL variables like 'innodb_default_row_format';		- default DYNAMIC
    The COMPRESSED row format, which is not supported for use in the system tablespace, cannot be defined as the default and can only be specified explicitly.

    When a ROW_FORMAT option is not specified explicitly or when ROW_FORMAT=DEFAULT is used, any operation that rebuilds a table also silently changes the row format of the table to that defined by innodb_default_row_format. Table-rebuilding operations include ALTER TABLE operations that use ALGORITHM=COPY or ALGORITHM=INPLACE where table rebuilding is required and the OPTIMIZE TABLE statement.

    Internal InnoDB temporary tables created by the server to process queries use the DYNAMIC row format, regardless of the innodb_default_row_format setting.

    Back


    The Federated storage engine

    For Federated tables, the table definition resides on the local server but the physical storage of data is handled on a remote server.

    A Federated table consists of two elements
  • a remote server with a database table, which consists of the table definition (stored in the MySQL data dictionary) and the associated table whose type may be any type supported by the remote mysqld server, including InnoDB.
  • a local server with a database table, where the table definition matches that of the corresponding table on the remote server and is stored in the data dictionary. There is no data file on the local server and the table definition includes a connection string that points to the remote table.

    Federated tables can be created

  • using CONNECTION
    	CREATE TABLE federated_table (
    	id	int(10) NOT NULL AUTO_INCREMENT,
    	name	VARCHAR(50),
    	PRIMARY KEY  (id),
    	INDEX name (name)
    	) ENGINE=FEDERATED DEFAULT CHARSET=utf8mb4 CONNECTION='mysql://fed_user@remote_host:3306/federated/table1';
  • using CREATE SERVER
    	CREATE SERVER fedlink FOREIGN DATA WRAPPER mysql OPTIONS (USER 'fed_user', HOST 'remote_host', PORT 3306, DATABASE 'federated');
    	CREATE TABLE federated_table (
    	id	int(10) NOT NULL AUTO_INCREMENT,
    	name	VARCHAR(50),
    	PRIMARY KEY  (id),
    	INDEX name (name)
    	) ENGINE=FEDERATED DEFAULT CHARSET=utf8mb4 CONNECTION='fedlink/table1';

    Back


    MySQL programs

    MySQL programs can be invoked from the command line followed by any options or other arguments. Options can also be specified using option (configuration) files or environment variables.

    mysqld

    mysqld, also known as MySQL Server, is the main program that does most of the work in a MySQL installation. MySQL Server manages access to the MySQL data directory that contains databases and tables. The data directory is also the default location for other information such as log files and status files. When MySQL server starts, it listens for network connections from client programs and manages access to databases on behalf of those clients.
    	shell> mysqld --verbose --help		 list mysqld startup options
    The default configuration file \etc\mysql\my.cnf can be used to override mysqld default options.

    mysql_upgrade

    mysql_upgrade examines all tables in all databases for incompatibilities with the current version of MySQL Server and also upgrades the system tables. If mysql_upgrade finds that a table has a possible incompatibility, it performs a table check and attempts a table repair. mysql_upgrade should be executed after each upgrade of MySQL.
    	shell> mysql_upgrade --protocol=tcp -P 3306 [other options]
    For local host connections on Unix, the --protocol=tcp option forces a connection using TCP/IP rather than the Unix socket file.


    MySQL client programs

    mysql

    mysql is the MySQL command-line client. It is a simple SQL shell with input line editing capabilities and supports interactive and non-interactive use. When used interactively, query results are presented in an ASCII-table format. When used non-interactively, the result is presented in a tab-separated format. The output format can be changed using command options.
    	shell> mysql -uusername -p -hhostname	- connect to a host, mysql interprets the first nonoption argument as a database name
    	
    	Options:
    	--binary-as-hex				- display binary values in hex notation (use --skip-binary-as-hex to disable)
    	--execute "stmt", -e			- execute statement and quit
    	--force, -f				- continue even if an SQL error occurs
    	--help, -?				- display information and exit
    	--host hostname, -hhost	 		- connect to mysql server on the given host
    	--local-infile				- enable LOCAL capability for LOAD DATA INFILE
    	--password=pwd -ppwd			- password to use, mysql will prompt if omitted
    	--port=num, -P num			- port number to use for the connection
    	--quick, -q				- don't cache query results, print each row as it is received
    	--show-warnings				
    	--user username, -uuser			- user name to connect to the server
    	--xml					- get output in xml format
    	shell> mysql db1 -uuser -p -hhost -e "select * from t1;" | sed 's/\t/|/g' > t1.txt   	- get output in pipe-delimited format
    mysql client commands

    mysql sends each SQL statement issued to the server to be executed. There is also a set of commands that mysql itself interprets. Typing help or \h at the mysql> prompt lists these commands.
    	clear (\c)	- clear the current input statement
    	exit (\q)	- exit mysql (same as quit)
    	help (\h)	- help
    	quit (\q)	- quit mysql
    	source (\.)	- execute an sql script file, takes file name as argument
    	use (\u)	- use another database, takes DB name as argument
    Executing SQL statements from a text file
    	shell> mysql db1 < file1.sql > out.txt
    	
    	mysql> source file1.sql		
    	mysql> \. file1.sql

    mysqlcheck

    The mysqlcheck client performs table maintenance - checks, repairs, optimizes or analyzes tables by using the SQL statements CHECK TABLE, REPAIR TABLE, ANALYZE TABLE and OPTIMIZE TABLE. Each table is locked and therefore unavailable to other sessions while it is being processed. mysqlcheck must be used when the mysqld server is running. Table maintenance operations can be time-consuming, particularly for large tables.
    	mysqlcheck -u user -p db_name tbl_name			- default option --check
    	mysqlcheck --repair -u user -p db_name tbl_name		- repair table

    Option (configuration) files

    Most MySQL programs can read startup options from option (configuration) files. Option files provide a convenient way to specify commonly used options so that they need not be entered on the command line each time when running a program.

    To determine whether a program reads option files, it can be invoked with the --help option (for mysqld, --verbose and --help). If the program reads option files, the help message indicates which files it looks for and which option groups it recognizes.
    	mysql --help
    	mysqld --verbose
    Option files read on Unix and Unix-like systems
    	File Name		Purpose
    	---------		-------
    	/etc/my.cnf		Global options
    	/etc/mysql/my.cnf	Global options
    	SYSCONFDIR/my.cnf	Global options
    Option files read on Windows systems
    	%WINDIR%\my.ini, %WINDIR%\my.cnf	Global options
    	C:\my.ini, C:\my.cnf			Global options
    	BASEDIR\my.ini, BASEDIR\my.cnf		Global options		BASEDIR = MySQL base installation directory
    The syntax for specifying options in an option file is similar to command-line syntax, except that in an option file, the leading two dashes are omitted from the option name and only one option per line is specified. Hyphens and underscores are both usable in option names. Comment lines start with # or ; and a # comment can start in the middle of a line.

    The [mysqld] and [mysql] groups apply to the mysqld server and the mysql client program respectively and the [client] group specifies options that apply to all clients.
    	[client]
    	port=3306
    	socket=/tmp/mysql.sock
    
    	[mysqld]
    	port=3306
    	socket=/tmp/mysql.sock
    	innodb_buffer_pool_size=16G
    	max_allowed_packet=128M
    
    	[mysqldump]
    	quick

    The data directory

    Information managed by the MySQL server is stored under a directory known as the data directory. The --datadir option enables the location of the data directory to be changed. Each subdirectory of the data directory is a database directory and corresponds to a database managed by the server.
    	SHOW GLOBAL VARIABLES LIKE 'datadir';	- data directory
    All MySQL installations have certain system databases - mysql - contains information required by the MySQL server as it runs
    information_schema - is a standard database, but its implementation uses no corresponding database directory
    performance_schema - provides information used to inspect the internal execution of the server at runtime
    sys - the sys schema provides a set of objects to help interpret Performance Schema information more easily
    ndbinfo - corresponds to the ndbinfo database that stores information specific to MySQL Cluster
    Other subdirectories may include - Log files written by the server, InnoDB tablespace and log files, Default/autogenerated SSL and RSA certificate and key files and the server process ID file (while the server is running).

    Copying an existing data directory

    An existing data directory can be copied over to create a new MySQL instance in the same server or a new server.

    1. Stop the existing MySQL instance using the data directory. This must be a clean shutdown so that the instance flushes any pending changes to disk
    2. Copy the data directory to a new location in the same server or a different server with MySQL installed
    3. Copy the existing my.cnf file and make relevant changes to point to the new data directory
    4. Start the new MySQL instance using the modified configuration file


    MySQL data dictionary

    MySQL server incorporates a transactional data dictionary that stores information about database objects. In earlier MySQL releases, dictionary data was stored in metadata files, nontransactional tables and storage engine-specific data dictionaries.

    Data dictionary tables are protected and may only be accessed in debug builds of MySQL, but data stored in data dictionary tables can be accessed through INFORMATION_SCHEMA tables and SHOW statements.

    The data dictionary schema stores dictionary data in transactional (InnoDB) tables that are located in the mysql database together with non-data dictionary system tables. Data dictionary tables are created in a single InnoDB tablespace named mysql.ibd, which resides in the data directory. Dictionary data is protected by the same commit, rollback and crash-recovery capabilities that protect user data stored in InnoDB tables.

    Dictionary Object Cache

    The dictionary object cache is a shared global cache that stores previously accessed data dictionary objects in memory to enable object reuse and minimize disk I/O. Similar to other MySQL cache mechanisms, the dictionary object cache uses an LRU-based strategy to evict objects from memory.

    The dictionary object cache comprises cache partitions that store different object types. Some cache partition size limits are configurable, whereas others are hardcoded.
  • tablespace definition cache partition - stores tablespace definition objects. The tablespace_definition_cache option sets a limit for the number of tablespace definition objects that can be stored in the dictionary object cache

  • schema definition cache partition - stores schema definition objects

  • table definition cache partition - stores table definition objects. The object limit is set to the value of max_connections, which has a default value of 151. The table definition cache partition exists in parallel with the table definition cache that is configured using the table_definition_cache option. Both caches store table definitions but serve different parts of the MySQL server and objects in one cache have no dependence on the existence of objects in the other

  • stored program definition cache partition - stores stored program definition objects. The stored program definition cache partition exists in parallel with the stored procedure and stored function caches that are configured using the stored_program_cache option. The stored_program_cache option sets a soft upper limit for the number of cached stored procedures or functions per connection and the limit is checked each time a connection executes a stored procedure or function. The stored program definition cache partition, on the other hand, is a shared cache that stores stored program definition objects for other purposes.

  • character set definition cache partition - stores character set definition objects and has a hardcoded object limit of 256

  • collation definition cache partition - stores collation definition objects and has a hardcoded object limit of 256
    	show global variables like 'tablespace_definition_cache';	- default 256
    	show global variables like 'schema_definition_cache';		- default 256
    	show global variables like 'table_definition_cache';		- default -1 (autosizing)
    	show global variables like 'stored_program_definition_cache';	- default 256
    	show global variables like 'stored_program_cache';		- default 256

    Internal temporary tables

    MySQL creates internal temporary tables while processing some statements like those using UNION, GROUP BY or derived tables. The Explain output for these statements shows Using temporary in the Extra column. An internal temporary table can be held in memory and processed by the MEMORY storage engine or stored on disk by the InnoDB storage engine.

    The maximum size of in-memory temporary tables is determined from whichever of the values of tmp_table_size and max_heap_table_size is smaller. If an in-memory temporary table exceeds the limit, MySQL automatically converts it to an on-disk temporary table that is created in the ibtmp1 temporary tablespace file in the data directory.

    For MEMORY tables explicitly created with CREATE TABLE, only the max_heap_table_size variable determines how large a table can grow and there is no conversion to on-disk format.
    	SHOW GLOBAL VARIABLES like 'tmp_table_size';	- maximum size of internal in-memory temporary tables
    	SHOW GLOBAL VARIABLES like 'max_heap_table_size';	- maximum size of MEMORY tables
    	SHOW GLOBAL VARIABLES like 'big_tables';	- if set to 1, all temp tables are created on disk (default=OFF)
    		
    	SHOW GLOBAL STATUS like 'Created%';
    		Created_tmp_tables		- number of internal temporary tables created while executing statements
    		Created_tmp_disk_tables;	- number of internal on-disk temp tables
    Temporary files

    On Unix, MySQL uses the value of the TMPDIR environment variable as the path name of the directory in which to store temporary files. If TMPDIR is not set, MySQL uses the system default, usually /tmp, /var/tmp or /usr/tmp. On Windows, MySQL checks in order the values of the TMPDIR, TEMP and TMP environment variables. If none of them are set, MySQL uses the system default, which is usually C:\windows\temp\.

    If the file system containing the temporary file directory is too small, the tmpdir option can be used to specify a directory in a file system where there is enough space.

    The tmpdir option can be set to a list of several paths that are used in round-robin fashion. Paths should be separated by colon characters (:) on Unix and semicolon characters (;) on Windows.
    	SHOW GLOBAL VARIABLES like 'tmpdir';	- path for temp files
    	SHOW GLOBAL STATUS like 'Created_tmp_files';	- number of temporary files created

    Back


    MySQL server logs

    Binary Log

    The binary log contains events that describe database changes via DCL and DML. It also contains events for statements that potentially could have made changes (for example, a DELETE which matched no rows), unless row-based logging is used. The binary log also contains information about how long each statement took that updated data. The binary log has two important purposes:
  • For replication, the binary log on a master replication server provides a record of the data changes to be sent to slave servers. The master server sends the events contained in its binary log to its slaves, which execute those events to sync with the master.
  • Certain data recovery operations require use of the binary log. After a backup is restored, the events in the binary log that were recorded after the backup was taken are re-executed to bring databases up to date from the point of the backup.

    The binary log consists of a set of files named using the base name appended with a sequence number, plus an index file that contains the file names to keep track of which files have been used. The server creates a new file in the series each time it starts, flushes the logs or when the maximum file size is reached.
    	SHOW BINARY LOGS;	- lists the binary log files
    	
    	SHOW GLOBAL VARIABLES LIKE '%binlog%';
    		binlog_cache_size	- the size of the cache to hold changes to the binary log during a transaction
    		max_binlog_size		- log file size, if exceeded the server opens a new log file
    		binlog_format		- the binary logging format, can be STATEMENT, ROW or MIXED
    		sync_binlog		- number of binary log commit groups to collect before synchronizing to disk
    		
    	SHOW GLOBAL VARIABLES LIKE 'log_bin%';
    		log_bin			- ON by default, can be used to specify a base name and location for the binary log
    		log_bin_basename	- the name and complete path to the binary log file
    		log_bin_index		- the index file for binary log file names
    The PURGE BINARY LOGS statement (needs SUPER or BINLOG_ADMIN privilege) deletes all the binary log files listed in the log index file prior to the specified log file name or date.
    	SHOW GLOBAL VARIABLES LIKE '%expire%';
    		expire_logs_days	- the number of days for automatic binary log file removal (0 - no auto removal)
    
    	PURGE BINARY LOGS TO 'mysql-bin.012';
    	PURGE BINARY LOGS BEFORE '2015-06-02 22:46:26';
    There are three logging formats:

    Statement - Replication in MySQL originally was based on propagation of SQL statements from master to slave, called statement-based logging
    Row - In row-based logging, the master writes events to the binary log that indicate how individual table rows are affected
    Mixed - With mixed logging, statement-based logging is used by default, but the logging mode switches automatically to row-based in certain cases

    The SHOW BINLOG EVENTS statement shows the events in the binary log. If the log name is not specified, the first binary log is displayed. It requires the REPLICATION SLAVE privilege.
    	SHOW BINLOG EVENTS LIMIT 20;	- shows events in the first binary log
    	SHOW BINLOG EVENTS IN 'mysql-bin.000220' FROM 594 LIMIT 10;		- shows events from pos 594
    SHOW BINLOG EVENTS displays the following fields for each event log_name - log that is being listed
    pos - position of the event
    event_type - describes the event type
    server_id - server id of the server where the event originated
    end_log_pos - the position at which the next event begins, equal to pos plus the size of the event
    info - information about the event
    When sync_binlog=0, the binary log is never synchronized to disk, and when sync_binlog is set to a value > 0 this number of binary log commit groups is periodically synchronized to disk. When sync_binlog=1, all transactions are synchronized to the binary log before they are committed and in the event of an unexpected restart, any transactions that are missing from the binary log are only in prepared state and will be rolled back by the server's automatic recovery routine. This guarantees that no transaction is lost from the binary log, and is the safest option. However this impacts performance because of an increased number of disk writes. Using a higher value improves performance with the increased risk of data loss.

    The sql_log_bin session variable controls whether logging to the binary log is enabled for the current session. Setting the variable to OFF prevents transactions in the current session from being written to the binary log or GTIDs being assigned to them.
    	SHOW VARIABLES LIKE 'sql_log_bin';	- default ON
    The general query log

    It is a general record of mysqld activity. 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 during troubleshooting to know exactly what a client sent to mysqld.

    mysqld writes statements to the query log in the order that it receives them which might differ from the order in which they are executed. If no name is specified for the general query log file, the default name is host_name.log created in the data directory.
    	SHOW GLOBAL VARIABLES LIKE 'general_log%';
    		general_log	-  whether general log is enabled (ON/OFF)
    		general_log_file	- file location
    	SHOW GLOBAL VARIABLES LIKE 'log_output';
    		log_output	- can contain one or more of options FILE,TABLE,NONE (Default=FILE)
    The error log

    The error log contains information indicating when mysqld was started and stopped and also any critical errors that occur while the server is running. If mysqld notices a table that needs to be automatically checked or repaired, it writes a message to the error log.
    	SHOW GLOBAL VARIABLES like 'log_error';	- error log file
    	SHOW GLOBAL VARIABLES like 'log_error_verbosity;	- the verbosity of the server in writing messages to the error log
    			1 - errors
    			2 - errors & warnings
    			3 = errors, warnings & informational messages (Default)
    The slow query log

    The slow query log consists of SQL statements that took more than long_query_time seconds to execute and required at least min_examined_row_limit rows to be examined. The minimum and default values of long_query_time are 0 and 10 respectively. The value can be specified to a resolution of microseconds.
    	SHOW GLOBAL VARIABLES LIKE 'long_query_time';
    	SHOW GLOBAL VARIABLES LIKE 'min_examined_row_limit';	- default 0
    	SHOW GLOBAL VARIABLES LIKE 'log_queries_not_using_indexes';	- default OFF
    	
    	SET GLOBAL long_query_time=1.500;
    	SET GLOBAL log_output='table';	- divert output to mysql.slow_log
    	
    	SHOW GLOBAL VARIABLES LIKE 'slow_query%';
    	SET GLOBAL slow_query_log=ON;
    	
    	SHOW GLOBAL STATUS like 'Slow_queries';	- number of queries that have taken more than long_query_time seconds
    The general and slow query log files can be cleared at runtime without a server restart by disabling the log, renaming the log file and enabling the log again.

    The DDL log or metadata log, records metadata operations generated by data definition statements such as DROP TABLE and ALTER TABLE. MySQL uses this log to recover from crashes occurring in the middle of a metadata operation.

    Back


    DATABASE OBJECTS

    Databases
    	SHOW DATABASES;		- list databases
    	SHOW DATABASES like '%test%';
    	
    	SELECT table_schema 'db', round(SUM(data_length + index_length)/1024/1024/1024,2) 'Size(GB)', round(SUM(data_length + 
    		index_length)/1024/1024,2) 'Size(MB)' FROM information_schema.tables GROUP BY table_schema;   - size of databases
    	SELECT table_schema, table_name, round(data_length/1024/1024,2) 'Data Size(MB)', round(index_length/1024/1024,2) 'Index Size(MB)' 
    		FROM information_schema.tables where table_schema = 'db1' ORDER BY data_length + index_length DESC; - large tables
    		
    	SELECT CONCAT('rename table db1.', table_name , ' to db2.' , table_name,';') FROM information_schema.TABLES
    		WHERE table_schema = 'db1';		- move tables
    The READ ONLY option controls modification of the database and objects within it. The permitted values are DEFAULT or 0 (not read only) and 1 (read only). This option is useful for database migration as a READ ONLY database can be migrated to another MySQL instance without concern that the database might be changed during the operation.
    	ALTER DATABASE db1 READ ONLY = 1;
    Information_schema

    Information_schema is a database within each MySQL instance that stores metadata information about all other databases. It contains several read-only tables that are actually views, not base tables, so there are no files associated with them and there is no database directory with that name.
    	select * from information_schema.schemata;	- information about databases
    	SELECT * FROM information_schema.TABLES where table_name = 't1' and table_schema = 'testdb';	- table details
    	SELECT table_name FROM information_schema.COLUMNS where table_schema = 'db1' AND column_name LIKE '%c1%'; - tables with column c1
    All MySQL users have the right to access most information_schema tables, but can see only the rows in the tables that correspond to objects for which the user has the proper access privileges. Tables with names beginning with INNODB_ require the PROCESS privilege.

    Tables

    A table can have a maximum of 1017 columns and 64 secondary indexes. The maximum table size is the maximum tablespace size which depends on the innodb_page_size (64TB for the default 16KB page size). The maximum row size for the default page size of 16KB is about 8000 bytes.
    	CREATE TABLE t1 (c1 int(10) unsigned auto_incement, c2 varchar(255), primary key (c1), key ix_1 (c2)) default charset=utf8;
    	
    	CREATE TABLE t1 LIKE t2; 	- create t2 modeled after t1
    
    	SHOW TABLES like '%pat%';	- lists tables and views
    	SHOW TABLE STATUS like '%pat%';	- lists table details
    	
    	DESC(RIBE) table1;  		- show table structure
    	SHOW CREATE TABLE table1;	- get create table syntax
    	SHOW COLUMNS/FIELDS from t1;	- display column information for tables/views
    Altering tables
    	RENAME TABLE t1 TO t2; - rename table
    
    	ALTER TABLE t1 ADD PRIMARY KEY(col1,col2);	- add primary key
    	ALTER TABLE t2 DROP PRIMARY KEY;		- drop primary key
    	
    	ALTER TABLE t1 ADD COLUMN col1 int unsigned AFTER col2;	- add a column
    	ALTER TABLE t1 ADD COLUMN col1 int FIRST;  		- add a column at the top
    	ALTER TABLE t1 ADD COLUMN col1 int PRIMARY KEY AUTO_INCREMENT FIRST;  - add an auto-increment column
    	ALTER TABLE t1 CHANGE OldCol NewCol DATATYPE;   - rename column
    	ALTER TABLE t1 DROP COLUMN col1;  		- drop a column	
    	
    	ALTER TABLE t1 MODIFY COLUMN col1 DATATYPE;	- change column definition
    	ALTER TABLE t1 ALTER col1 SET DEFAULT 'abc';	- change default value
    	ALTER TABLE t1 MODIFY COLUMN col1 VARCHAR(50) AFTER col2;   - move a column
    	ALTER TABLE t1 MODIFY `id` int unsigned, DROP PRIMARY KEY, ADD PRIMARY KEY (`uid`);  - drop auto-incr primary key
    	ALTER TABLE t1 MODIFY col1 int COMMENT 'comment';	- add a comment for column
    
    	ALTER TABLE t1 ENGINE = InnoDB;   - change storage engine
    	
    	ALTER TABLE t1 AUTO_INCREMENT = 5;	- set next value of auto_increment column
    Constraints

    Creation of a foreign key constraint requires the REFERENCES privilege for the parent table. Corresponding columns in the foreign key and the referenced key must have similar data types. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.

    When an UPDATE or DELETE operation affects a key value in the parent table that has matching rows in the child table, the result depends on the referential action specified using ON UPDATE and ON DELETE subclauses of the FOREIGN KEY clause. MySQL supports five options
  • CASCADE - automatically delete or update the matching rows in the child table. Cascaded foreign key actions do not activate triggers
  • SET NULL - set the foreign key column or columns in the child table to NULL. The columns in the child table should not be declared as NOT NULL
  • RESTRICT - rejects the delete or update operation for the parent table, this is the default action
  • NO ACTION - a keyword from standard SQL, equivalent to RESTRICT
  • SET DEFAULT - this action is recognized by the MySQL parser, but both InnoDB and NDB reject table definitions containing ON DELETE SET DEFAULT or ON UPDATE SET DEFAULT clauses
    	ALTER TABLE t1 ADD CONSTRAINT cons_name FOREIGN KEY (col1) REFERENCES t2(col2);		- add a foreign key
    	ALTER TABLE tl DROP FOREIGN KEY fk1;	- drop foreign key
    	SELECT * FROM information_schema.table_constraints WHERE constraint_type = 'FOREIGN KEY';	- list all foreign keys
    	SELECT * FROM information_schema.key_column_usage WHERE referenced_table_name = 'tbl'
    			AND referenced_column_name = 'col1' AND table_schema = 'db1';	- foreign keys pointing to a column
    
    	SET foreign_key_checks = 0;	- ignore foreign key constraints for current session
    	
    	ALTER TABLE t1 ADD CONSTRAINT cons_name UNIQUE (col1,col2);	- add a unique constraint
    	ALTER TABLE t1 DROP INDEX uq_ix;	- drop a unique constraint
    Temporary tables

    Temporary tables are created by using the TEMPORARY keyword - CREATE TEMPORARY TABLE. A temp table is visible only to the current connection, and is dropped automatically when the connection is closed. This means that two different connections can use the same temporary table name without conflicting with each other.

    Compressing tables

    An InnoDB table created with ROW_FORMAT=COMPRESSED has compression enabled and can use a smaller page size on disk than the configured innodb_page_size value. Smaller pages require less I/O to read from and write to disk.
    	CREATE TABLE t1 (c1 int(10) unsigned PRIMARY KEY) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
    If ROW_FORMAT=COMPRESSED is used, KEY_BLOCK_SIZE can be omitted and the default compressed page size of 8KB is used. If KEY_BLOCK_SIZE is used, ROW_FORMAT=COMPRESSED can be omitted and compression is enabled automatically.

    In the buffer pool, the compressed data is held in small pages, with a page size based on the KEY_BLOCK_SIZE value. For extracting or updating the column values, MySQL also creates an uncompressed page in the buffer pool with the uncompressed data and any updates to the uncompressed page are also written to the equivalent compressed page.

    Partitioning

    Partitioning makes it possible to store more data in one table than can be held on a single disk or file system partition. Redundant data can be easily removed by dropping the partition containing only that data. Some queries can be greatly optimized if data satisfying a given WHERE clause is stored only on one or more partitions.
    	SELECT * FROM t PARTITION (p0,p1) WHERE c < 5;	- selects only those rows in partitions p0 and p1
    Partitioning types
  • RANGE - assigns rows to partitions based on column values falling within a given range. If the column value is NULL, the row is assigned to the lowest partition
  • LIST - similar to RANGE, except that the partition is selected based on columns matching one of a set of discrete values. Rows with NULL column values are admitted only if one of partitions is defined with NULL in its value list
  • HASH - a partition is selected based on the value returned by a user-defined expression that operates on column values in rows to be inserted into the table. The function may consist of any expression valid in MySQL that yields a nonnegative integer value

    A partitioning key must be either an integer column or an expression that resolves to an integer.
    	CREATE TABLE t1 (
    	    emp_id int not null,
    	    store_id int not null )
    	partition by range (store_id) (
    	    partition p0 values less than (25),
    	    partition p1 values less than (50),
    	    partition p2 values less than (100));
    		
    	ALTER TABLE t1 ADD PARTITION (partition p3 values less than (200));
    	ALTER TABLE t1 DROP PARTITION p0;
    Every unique key on a partitioned table (including the primary key) must use every column in the table's partitioning expression. Also, partitioned tables using the InnoDB storage engine do not support foreign keys.

    Partition management

    Rebuilding partitions has the same effect as dropping all records stored in the partition and then reinserting them and is useful for defragmentation.
    	ALTER TABLE t1 REBUILD PARTITION p0, p1;
    	ALTER TABLE t1 TRUNCATE PARTITION p0;
    	ALTER TABLE t1 TRUNCATE PARTITION ALL;	- truncate all partitions
    Defragmenting a table

    Random insertions/deletions from a secondary index can cause the index to become fragmented. Fragmentation means that the physical ordering of the index pages on the disk is not close to the index ordering of the records on the pages, or that there are many unused pages in the 64-page blocks that were allocated to the index.
    	ALTER TABLE tbl_name FORCE;		-  performs a null alter operation that rebuilds the table
    Online DDL

    The InnoDB online DDL feature permits in-place table alterations or concurrent DML by using the LOCK and ALGORITHM clauses of the ALTER TABLE statement. ALGORITHM=INSTANT - only modifies metadata in the data dictionary. An exclusive metadata lock on the table may be taken briefly during the execution phase of the operation ALGORITHM=INPLACE - alters table without copying. Permits concurrent DML ALGORITHM=COPY - copies the table LOCK=EXCLUSIVE - blocks access to the table entirely LOCK=SHARED - allows queries but not DML LOCK=NONE - allows full query and DML access to the table LOCK=DEFAULT or omitting the LOCK clause - permits as much concurrency as possible depending on the type of DDL operation ALGORITHM=INSTANT is used by default or supported for adding, dropping and renaming columns, setting or dropping column default values and renaming tables. ALGORITHM=INPLACE is supported for adding, dropping or renaming secondary indexes, dropping a primary key and adding another, for adding foreign key constraints (with foreign_key_checks disabled) and dropping foreign keys.

    The innodb_online_alter_log_max_size option specifies an upper limit in bytes on the size of the temporary log files used during online DDL operations. There is one log file for each index being created or table being altered that stores data inserted, updated or deleted in the table during the DDL operation. The temporary log file is extended when needed by the value of innodb_sort_buffer_size up and if it exceeds the upper size limit, the ALTER TABLE operation fails and all uncommitted concurrent DML operations are rolled back. Thus, a large value for this option allows more DML to happen during an online DDL operation, but also extends the period of time at the end of the DDL operation when the table is locked to apply the data from the log.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_online_alter_log_max_size';  - default 128MB

    Indexes

    Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions are that indexes on spatial data types use R-trees and that MEMORY tables also support hash indexes. Spatial indexes are only available on MyISAM tables.

    When a primary key is defined on a table, InnoDB uses it as the clustered index. If not, MySQL locates the first unique index where all the key columns are NOT NULL and InnoDB uses it as the clustered index. If the table has no primary key or suitable unique index, InnoDB internally generates a hidden clustered index named GEN_CLUST_INDEX on a synthetic column containing row ID values. The rows are ordered by the ID that InnoDB assigns to the rows in such a table. The row ID is a 6-byte field that increases monotonically as new rows are inserted. Thus, the rows ordered by the row ID are physically in insertion order.

    In InnoDB, each record in a secondary index contains the primary key columns for the row, as well as the columns specified for the secondary index. InnoDB uses this primary key value to search for the row in the clustered index. If the primary key is long, the secondary indexes use more space, so it is advantageous to have a short primary key.

    An index can consist of upto 16 columns. In a multi-column index, any leftmost prefix of the index can be used by the optimizer to find rows.

    The cardinality of an index is the estimated number of unique values in the index. The higher the cardinality, the greater the chance that MySQL uses the index.
    	CREATE INDEX ix1 ON  t1 (col1, col2, col3);		- create index
    	CREATE UNIQUE INDEX ix1 ON  t1 (col1, col2, col3);	- create a unique index (unique columns can have nulls)
    	ALTER TABLE t1 ADD INDEX ix1(c1), ADD INDEX ix2(c2), ALGORITHM=INPLACE, LOCK=NONE;	- add an index without locking table
    	
    	ALTER TABLE tl DROP INDEX ix1;	- drop index
    	
    	SHOW INDEX FROM db1.tbl1;	- returns table index information
    
    	SELECT distinct table_name, index_name from information_schema.statistics where table_schema = 'db1';	- list all indexes
    	SELECT * FROM information_schema.tables t LEFT JOIN information_schema.statistics s ON t.table_name = s.table_name
    		WHERE s.table_name is null AND t.table_schema = 'db1';		- tables with no indexes
    	
    	SELECT t.table_schema, t.table_name FROM  information_schema.tables t LEFT JOIN information_schema.statistics s
    	    ON t.table_schema=s.table_schema AND t.table_name=s.table_name AND s.non_unique=0 
    		WHERE s.table_name IS NULL AND t.table_schema = 'db1';		- tables with no primary key
    
    	SELECT object_schema, object_type, object_name, index_name FROM performance_schema.table_io_waits_summary_by_index_usage 
    		WHERE object_schema = 'db1' AND index_name IS NOT NULL AND count_star = 0 ORDER BY object_schema, object_type, object_name;
    											- unused indexes 
    	
    	SELECT p.object_schema, p.object_type, p.object_name, p.index_name, (i.stat_value * @@innodb_page_size) /1024/1024  'index_size'
    		FROM performance_schema.table_io_waits_summary_by_index_usage p, mysql.innodb_index_stats i 
    		WHERE i.stat_name='size' AND p.object_schema = i.database_name AND p.object_name = i.table_name AND p.index_name = i.index_name 
    		AND object_schema = 'db1' AND p.index_name IS NOT NULL AND p.index_name <> 'PRIMARY' AND p.count_star = 0 
    		ORDER BY index_size DESC;		- unused indexes by size
     	   
     	SELECT object_schema, object_type, object_name, count_read FROM performance_schema.table_io_waits_summary_by_index_usage 
     		WHERE object_schema = 'db1' AND index_name IS NULL AND count_read > 0 ORDER BY count_read desc limit 20;	
    																- full table scans with rows read
     	
     	SELECT object_schema, object_type, object_name, index_name, count_read FROM performance_schema.table_io_waits_summary_by_index_usage 
     	        WHERE object_schema = 'db1' AND object_name = 't1' ORDER BY count_read desc;	- rows read by index 	
    	
    	SELECT * from t1 FORCE INDEX (ix_t1_c1), t2 where t1.c1 = t2.c1;	- force index usage
    Full-text indexes

    Full-text indexes are of FULLTEXT type and can be created only for text-based columns (CHAR, VARCHAR or TEXT) to help speed up queries on data in those columns, omitting any words that are defined as stopwords.

    For large data sets, it is much faster to load the data into a table that has no FULLTEXT index and then create the index than to load data into a table that has an existing FULLTEXT index.
    	CREATE FULLTEXT INDEX ix_ft_col1 ON tbl1(col1);
    Full-text searching is performed using MATCH() ... AGAINST syntax. MATCH() takes a comma-separated list that names the columns to be searched and AGAINST takes a string to search for and an optional modifier that indicates the type of search to perform.
    	SELECT id, name, MATCH(name) AGAINST ('search_string') AS relevancy FROM table1;	- perform a fulltext index search
    	
    	SELECT * FROM articles  WHERE MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE);	- perform a natural language search
    	
    	SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;	- default stopword list
    Boolean full-text searches can be performed using the IN BOOLEAN MODE modifier. The + and - operators indicate that a word must be present or absent, respectively, for a match to occur.
    	SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
    		- retrieves all the rows that contain the word 'MySQL' and do not contain the word 'YourSQL'

    Back



    Stored objects

    Stored objects include these object types
  • Views
  • Stored routines - stored procedures and functions
  • Triggers
  • Events

    Stored routines, triggers and events are together referred to as stored programs.

    Views

    MySQL supports views, including updatable views. Views are stored queries that when invoked produce a result set. A view acts as a virtual table.

    The optional ALGORITHM clause for CREATE/ALTER VIEW is a MySQL extension to standard SQL. It affects how MySQL processes the view. ALGORITHM takes three values: MERGE, TEMPTABLE, or UNDEFINED.
  • For MERGE, the text of a statement that refers to the view and the view definition are merged such that parts of the view definition replace corresponding parts of the statement.
  • For TEMPTABLE, the results from the view are retrieved into a temporary table, which then is used to execute the statement.
  • For UNDEFINED, MySQL chooses which algorithm to use. It prefers MERGE over TEMPTABLE because MERGE is usually more efficient and a TEMPTABLE view cannot be updatable

    In TEMPTABLE views, locks can be released on underlying tables after the temporary table has been created and before it is used to finish processing the statement. This might result in quicker lock release than the MERGE algorithm.

    For a view to be updatable, there must be a one-to-one relationship between the rows in the view and the rows in the underlying table. A view is not updatable if it contains aggregate functions or window functions, DISTINCT, GROUP BY, HAVING, UNION/UNION ALL and certain subqueries and joins. MySQL sets a view updatability flag at CREATE VIEW time if update operations are legal for the view. The IS_UPDATABLE column in the information_schema.VIEWS table displays the status of this flag.
    	select * from information_schema.views;		- metadata about views
    Stored routines

    A stored routine is either a procedure or a function. A stored procedure is invoked using the CALL statement and does not have a return value but can modify its parameters for later inspection by the caller. It can also generate result sets to be returned to the client program.

    A stored function is used much like a built-in function, invoked in an expression and returns a value
    	SHOW PROCEDURE STATUS WHERE db = 'db1';		- list procedures
    	SHOW FUNCTION STATUS;	- list functions
    
    	SHOW CREATE PROCEDURE proc1;	- display procedure
    	SHOW CREATE FUNCTION func1;
    To use SHOW CREATE PROCEDURE/FUNCTION, the global SELECT privilege is required. The information_schema.ROUTINES table provides information about stored routines.
    	SELECT * FROM information_schema.routines where routine_type = 'FUNCTION' and routine_name = 'func1';
    	SELECT * FROM information_schema.routines where routine_type = 'PROCEDURE' and routine_name = 'proc1';
    Creating stored routines

    Stored routines are created with the CREATE PROCEDURE and CREATE FUNCTION statements, which require the CREATE ROUTINE privilege. If the DEFINER clause is present, the privileges required depend on the user value. If binary logging is enabled, CREATE FUNCTION might require the SUPER privilege. By default, MySQL automatically grants the ALTER ROUTINE and EXECUTE privileges to the routine creator. This behavior can be changed by disabling the automatic_sp_privileges variable.
    	CREATE [DEFINER = user] PROCEDURE sp_name ([proc_parameter[,...]])
    	[characteristic ...] routine_body
    
    	CREATE [DEFINER = user] FUNCTION fn_name ([func_parameter[,...]])
    	RETURNS type
    	[characteristic ...] routine_body
    	
    	characteristic:
    		COMMENT 'string'
    		LANGUAGE SQL
    		[NOT] DETERMINISTIC
    		CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA
    		SQL SECURITY { DEFINER | INVOKER }
    The parameter list enclosed within parentheses must always be present. If there are no parameters, an empty parameter list of () should be used. For procedures, parameters are specified as IN, OUT or INOUT before the parameter name. An IN parameter passes a value into a procedure and an OUT parameter passes a value from the procedure back to the caller. Each parameter is an IN parameter by default. For a function, parameters are always regarded as IN parameters.

    The RETURNS clause is mandatory for functions and indicates the return type of the function and the function body must contain a RETURN value statement.

    A routine is considered deterministic if it always produces the same result for the same input parameters and not deterministic otherwise. The default is NOT DETERMINISTIC. If binary logging is enabled, a CREATE FUNCTION statement must specify at least one of DETERMINISTIC, NO SQL or READS SQL DATA explicitly to declare that either the function is deterministic or it does not modify data. Also stored function creators/alterers must have the SUPER privilege in addition to the CREATE ROUTINE/ALTER ROUTINE privilege to safeguard against unsafe statements.

    To drop a stored routine, the ALTER ROUTINE privilege is required for it.
    	DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name;
    The ALTER PROCEDURE/FUNCTION statement can be used to change the characteristics of a stored routine. However, the parameters or body of a stored routine cannot be changed using this statement and to make such changes, the routine must be dropped and re-created. The ALTER ROUTINE privilege for the routine is required for ALTER PROCEDURE/FUNCTION.

    The CALL statement invokes a stored procedure. The EXECUTE privilege enables use of statements that execute stored routines.
    	CALL sp_name([parameter[,...]]);
    	CALL sp_name[()];
    Sample routines
    	DELIMITER $$
    	USE `SAMPLEDB`$$
    	DROP PROCEDURE IF EXISTS usp_getCity$$
    
    	CREATE DEFINER=`root`@`localhost` PROCEDURE usp_getCity(IN cityid INT, OUT cityname VARCHAR(50))
    	BEGIN
    		IF cityid = 0 THEN
    			SET cityname = NULL
    		ELSE
    			SELECT city into cityname FROM city where city_id = cityid;
    		END IF;           
    	END$$
    	DELIMITER ;
    
    	call usp_getCity (1, @city);
    	select @city;
    	
    	CREATE FUNCTION hello (s CHAR(20))
    		RETURNS CHAR(50) DETERMINISTIC
    		RETURN CONCAT('Hello, ',s,'!');
    Triggers

    A trigger is a named database object associated with a table and activated when an event (like insert or update) occurs for the table.

    The TRIGGER privilege is needed to display/create/drop/execute triggers.
    	SHOW TRIGGERS;			- list triggers in current database
    	SHOW TRIGGERS like 'tbl%';	- show triggers for specific tables
    	SELECT * FROM information_schema.triggers;
    	SHOW CREATE TRIGGER trig1;
    The below sample trigger is invoked when the stock table is updated.
    	DELIMITER $$
    	DROP TRIGGER /*!50032 IF EXISTS */ `trig1`$$
    	CREATE /*!50017 DEFINER = 'root'@'%' */	TRIGGER `trig1` AFTER UPDATE ON `stock`
    		FOR EACH ROW BEGIN 
    	DECLARE stockqty DOUBLE;
    	DECLARE productid TINYINT;
    	DECLARE storeid INT;
    	SELECT quantity INTO stockqty FROM stock s WHERE s.store_id = NEW.store_id AND s.product_id = NEW.product_id;
    	IF stockqty < 500 THEN	
    		INSERT INTO low_stock (store_id, product_id) VALUES (NEW.store_id, NEW.product_id);
    	END IF;	
    	END;
    	$$
    	DELIMITER ;
    With statement-based replication, triggers executed on the master also execute on the slave. With row-based replication, triggers do not execute on the slave and the row changes on the master resulting from trigger execution are replicated and applied.


    Events

    An event is a task that the server runs according to a schedule. The MySQL event scheduler manages the scheduling and execution of events, which are named database objects containing one or more SQL statements. The event scheduler is implemented as a special thread. When running, the event scheduler thread and its current state can be seen in the output of SHOW PROCESSLIST with the PROCESS privilege.
    	SHOW GLOBAL VARIABLES LIKE 'event_scheduler';  - whether event scheduler is enabled (ON/OFF/DISABLED)
    If event_scheduler has not been set to DISABLED, it can be toggled between ON and OFF.

    The EVENT privilege is needed to create, drop or show events. The event scheduler writes information about event execution that terminates with an error or warning to the MySQL error log.

    Metadata about events can be obtained in the following ways
    	SHOW EVENTS;	- list events in current database
    	SHOW EVENTS FROM db1;
    	SHOW CREATE EVENT event1;
    	
    	select * from information_schema.events;
    		last_executed - time the event last executed
    Creating an event

    An event is associated with a schema and is created in the default schema or the schema qualifying the event name.
    	DROP EVENT IF EXISTS db1.event1;
    	delimiter |
    
    	CREATE EVENT db1.event1
    		ON SCHEDULE EVERY 1 DAY STARTS CURRENT_TIMESTAMP + interval 1 hour
    		COMMENT 'Saves and clears table each day'
    		DO BEGIN
    			INSERT INTO t1_backup SELECT * FROM t1;
    			TRUNCATE TABLE t1;
    		  END |
    	delimiter ;
    When an event is created on a replication master, the status of the event is set to SLAVESIDE_DISABLED on the slave. When promoting such slaves to be a master, those events need to be enabled.
    	SELECT event_schema, event_name FROM information_schema.events WHERE status = 'SLAVESIDE_DISABLED';
    	ALTER EVENT event1 ENABLE/DISABLE/DISABLE ON SLAVE;		- enable/disable event

    Access control for stored programs and views

    Stored programs and views, when referenced, execute within a security context whose privileges are controlled by the DEFINER attribute and the SQL SECURITY characteristic.
    	CREATE DEFINER = 'admin'@'localhost' PROCEDURE p1()
    	SQL SECURITY DEFINER/INVOKER	
    	BEGIN ... END
    All stored programs (procedures, functions, triggers and events) and views can have a DEFINER attribute that names a MySQL account. If the DEFINER attribute is omitted, the default account is the user who creates the object. The SET_USER_ID or SUPER privilege is required to specify any account as the DEFINER attribute. Additionally, to set the DEFINER attribute to an account that has the SYSTEM_USER privilege, SYSTEM_USER privilege is needed. Otherwise, the only permitted definer is the current user.

    In addition, stored routines (procedures and functions) and views can have an SQL SECURITY characteristic with a value of DEFINER or INVOKER to specify the context that the object executes in. If omitted, the default is definer context.

    Triggers and events have no SQL SECURITY characteristic and always execute in definer context, as there is no invoking user.


    Object names

    Object names are known as identifiers. An identifier may be quoted or unquoted. If an identifier contains special characters or is a reserved word it must be quoted whenever it is referred, with one exception. A reserved word that follows a period in a qualified name must be an identifier, so it need not be quoted. The identifier quote character is the backtick (`).

    Internally, identifiers are converted to and are stored as Unicode (UTF-8).
  • Permitted characters in unquoted identifiers
    	ASCII: [0-9,a-z,A-Z$_] (basic Latin letters, digits 0-9, dollar, underscore)
    	Extended: U+0080 .. U+FFFF
  • Permitted characters in quoted identifiers
    	ASCII: U+0001 .. U+007F
    	Extended: U+0080 .. U+FFFF
  • ASCII NUL (U+0000) and supplementary characters (U+10000 and higher) are not permitted in quoted or unquoted identifiers
  • Identifiers may begin with a digit but unless quoted may not consist solely of digits
  • Database, table and column names cannot end with spaces

    Since databases, tables and triggers have a folder or file named after them, consequently, the case sensitivity of the underlying OS plays a part in the case sensitivity of database, table and trigger names. The names are not case-sensitive in Windows but are case-sensitive in most varieties of Unix.

    The lower_case_table_names system variable affects how table and database names are stored on disk and used in MySQL. It can only be configured when initializing the server and changing it after the server is initialized is prohibited.
    	show global variables like 'lower_case_table_names';	- default 0 on Unix and 1 on Windows
    		0 - table names are stored as specified and comparisons are case-sensitive
    		1 - table names are stored in lowercase on disk and comparisons are not case sensitive
    		2 - table names are stored as given but compared in lowercase

    Back



    MySQL LANGUAGE

    Data types

    Numeric

    Fixed-point - The DECIMAL and NUMERIC types store exact numeric data values and are used when it is important to preserve exact precision, for example with monetary data.
    	DECIMAL(precision,scale)/NUMERIC(precision,scale)		e.g DECIMAL(5,2) - 5 digits total, 2 after decimal point, can store values from -999.99 to 999.99
    Values for DECIMAL/NUMERIC columns are represented using a binary format that packs nine decimal (base 10) digits into four bytes. Storage for the integer and fractional parts of each value are determined separately. Each multiple of nine digits requires four bytes and the leftover digits require a fraction of four bytes.

    Floating-point - The FLOAT and DOUBLE types represent approximate numeric data values and are used for scientific and mathematical calculations where fractional precision is required.
    	FLOAT		4-bytes		single-precision
    	DOUBLE, REAL	8-bytes		double-precision
    MySQL also supports the optional precision specification, but the precision value in FLOAT(p) is used only to determine storage size. A precision from 0 to 23 results in a 4-byte FLOAT column and a precision from 24 to 53 results in an 8-byte DOUBLE column.
    	FLOAT(p)
    Integer - MySQL supports the SQL standard integer types INTEGER (or INT) and SMALLINT and as an extension, also supports the types TINYINT, MEDIUMINT and BIGINT, with the below required storage and range.
    	TINYINT		1 byte		0-255 (unsigned), -128 to 127 (signed)	
    	SMALLINT	2 bytes		0-65535, -32768 to 32767 
    	MEDIUMINT	3 bytes		0-16777215, -8388608 to 8388607 
    	INT/INTEGER	4 bytes		0-4294967298, -2147483648 to 2147483647 
    	BIGINT		8 bytes		0 to 264-1,-263-1 to 263-1
    Bit-value - The BIT data type is used to store bit values.
    	BIT(n)	n = 1 to 64		- needs approximately (n+7)/8 bytes
    String

    The string data types are CHAR, VARCHAR, BINARY, VARBINARY, BLOB, TEXT, ENUM and SET.
    	CHAR					fixed-length (0-255)
    	VARCHAR					variable length (0-65535), uses a 1 or 2 byte length prefix before the data
    	BINARY/VARBINARY 			binary strings
    	TINYTEXT/TEXT/MEDIUMTEXT/LONGTEXT	character strings of length 2^8-1 (255B), 2^16-1 (32KB), 2^24-1 (16MB), 2^32-1 (4GB)
    	TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB	binary large object (binary strings)  
    	ENUM	a string object with a value chosen from a list of permitted values that are enumerated explicitly in the column specification at table 
    		creation time
    		ENUM('value1','value2',...)		1 or 2 bytes, depending on the number of enumeration values (65,535 values maximum)
    	SET	a string object whose values are chosen from a list of permitted values specified when the table is created
    		SET('value1','value2',...)	1, 2, 3, 4, or 8 bytes, depending on the number of set members (64 members maximum)
    Date/Time

    The date and time data types for representing temporal values are DATE, TIME, DATETIME, TIMESTAMP and YEAR.
    	DATE		3 bytes		YYYY-MM-DD
    	DATETIME	5 bytes		YYYY-MM-DD HH:MM:SS
    	TIMESTAMP	4 bytes		YYYY-MM-DD HH:MM:SS (UTC)
    	TIME		3 bytes		HH:MM:SS or HHH:MM:SS(for time intervals)
    	YEAR		1 byte		YYYY
    MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. If time zone is changed, the retrieved timestamp value is different from the value that was stored.

    MySQL permits storing a zero value of '0000-00-00' as a 'dummy date' as in some cases, it is more convenient than using NULL values and uses less data and index space. To disallow this, strict sql mode can be enabled.

    MySQL has fractional seconds support for TIME, DATETIME and TIMESTAMP values, with up to microseconds (6 digits) precision. The syntax type_name(fsp) is used to define a column that includes a fractional seconds part, where type_name is TIME, DATETIME or TIMESTAMP and fsp is the precision - e.g. DATETIME(3). The fsp value must be in the range 0 to 6, 0 signifying no fractional part. Inserting a TIME, DATE, or TIMESTAMP value with a fractional seconds part into a column of the same type but having fewer fractional digits results in rounding.

    Literals

    Bit-value
    	b'01' (or B'01')
    	0b01
    Boolean
    	TRUE,true	- evaluates to 1
    	FALSE,false	- 0
    Hexadecimal
    	x'01AF' (or X'01AF')
    	0x01AF
    String
    	'string'
    	"string"
    	
    	Special Character Escape Sequences
    	\0	An ASCII NUL (X'00') character
    	\'	single quote
    	\"	double quote
    	\b	backspace
    	\n	newline (linefeed)
    	\r	carriage return
    	\t	tab
    	\\	backslash
    A character string/hexadecimal/bit-value literal may have an optional character set introducer and COLLATE clause to designate it as a string that uses a particular character set and collation.
    	[_charset_name] literal [COLLATE collation_name]

    Operators

    Arithmetic
    	%, MOD	modulo operator
    	*	multiplication
    	+	addition
    	-	minus
    	/	division
    	DIV	integer division, discards any fractional part
    	-	change the sign of the argument
    Assignment
    	:=	assign a value
    	=	assign a value (in SET or UPDATE statements)
    Bitwise
    	&	bitwise AND
    	>>	right shift
    	<<	left shift
    	^	bitwise XOR
    	|	bitwise OR
    	~	bitwise inversion
    Comparison
    	>	greater than
    	>=	greater than or equal
    	<	less than
    	<=	less than or equal
    	=	equal
    	<=>	NULL-safe equal to operator
    	<>, !=	not equal operator
    	
    	IN()			whether a value is within a set of values
    	IS, IS NOT		test a value against a boolean
    	IS NULL, IS NOT NULL	NULL value test
    	LIKE			simple pattern matching
    	BETWEEN..AND..		whether a value is within a range of values
    	REGEXP, RLIKE		whether string matches regular expression
    	SOUNDS LIKE		compare sounds
    Logical
    	AND, &&	logical AND
    	OR, ||	logical OR
    	XOR	logical XOR
    	NOT, !	negates value

    Statements

    Administrative statements

    FLUSH - used to flush internal caches, tables and logs. It needs the RELOAD privilege FLUSH HOSTS - empties the host cache and the Performance Schema host_cache table that exposes the cache contents and unblocks any blocked hosts. The host cache needs to be flushed when a legitimate host is blocked from connecting (based on max_connect_errors) or when the host IP has been changed
    	FLUSH HOSTS;
    FLUSH LOGS - closes and reopens any log file to which the server is writing. A new binary log or relay log file is created with the sequence number incremented by one. The general log and slow log files are just closed and reopened
    	FLUSH LOGS;
    FLUSH TABLES - closes all open tables, forces all tables in use to be closed and flushes the prepared statement cache
    	FLUSH TABLES;
    	FLUSH TABLES t1, t2;	- flushes tables t1 and t2
    	FLUSH TABLES WITH READ LOCK;	- closes all open tables and locks all tables in all databases with a global read lock
    KILL - kills a connection thread or the statement being executed by the connection. CONNECTION_ADMIN or SUPER privilege is required to kill threads/statements owned by others
    	KILL processlist_id;	- terminates the connection associated with the given processlist_id
    	KILL CONNECTION processlist_id;	- same as KILL
    	KILL QUERY processlist_id;	- terminates the statement that the connection is executing, leaving the connection intact
    processlist_id can be determined from the ID column of the INFORMATION_SCHEMA.PROCESSLIST table, the Id column of SHOW PROCESSLIST output and the PROCESSLIST_ID column of the performance_schema.threads table

    OPTIMIZE TABLE - reorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table
    	OPTIMIZE TABLE t1;
    SET - assigns values to variables
    	SET @var1 = expr1;	- user-defined variable assignment
    	SET @var1 = (SELECT SUM(col1) FROM t1);
    	SET var1 = expr2;	- stored program variable assignment
    	SET GLOBAL sysvar = value;	- system variable assignment
    	SET @@GLOBAL.sysvar = value;
    SHOW - provides information about database objects and server status
    	SHOW ERRORS;	- similar to SHOW WARNINGS but only displays errors
    	SHOW WARNINGS;	- displays the errors, warnings and notes resulting from execution of the most recent non-diagnostic 
    				statement in the current session
    Control flow statements

    IF
    	IF n > m THEN SET s = '>';
    	ELSEIF n = m THEN SET s = '=';
    	ELSE SET s = '<';
    	END IF;
    LOOP - implements a simple loop construct, enabling repeated execution of the statement list until the loop is terminated by a LEAVE statement. Within a stored function, RETURN can also be used, which exits the function entirely. Neglecting to include a loop-termination statement results in an infinite loop.
    	label1: LOOP
    		statements;
    		ITERATE label1;
    		LEAVE label1;
    	END LOOP label1;
    REPEAT - the statement list within a REPEAT statement is repeated until the search_condition expression is true. Thus, a REPEAT always enters the loop at least once.
    	label1: REPEAT
    		statements;
    		UNTIL search_condition;
    		END REPEAT label1;
    WHILE
    	WHILE condition DO
    		statements;
    	END WHILE;

    DDL statements

    ALTER TABLE - To use ALTER TABLE, ALTER, CREATE and INSERT privileges for the table are needed
    CREATE TABLE - requires the CREATE privilege
    RENAME TABLE - Renaming a table requires ALTER and DROP on the old table and ALTER, CREATE and INSERT on the new table
    TRUNCATE TABLE - empties a table completely. To achieve high performance, TRUNCATE TABLE bypasses the DML method of deleting data and logically is similar to a sequence of DROP TABLE and CREATE TABLE statements. It does not cause ON DELETE triggers to fire, it cannot be performed for tables with foreign keys pointing to them and it cannot be rolled back like a DML operation. It requires the DROP privilege.
    	TRUNCATE TABLE t1;

    DML statements

    DELETE
    	DELETE t1 FROM tbl1 t1, tbl2 t2 where t1.c1 = t2.c2;
    	DELETE t1 FROM tbl1 t1 LEFT JOIN (SELECT * FROM tbl1 LIMIT 10) t2 ON t1.id = t2.id 
    		WHERE t1.id IS NULL;	- delete all but top 10 rows
    INSERT
    	INSERT INTO t1 (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);	- insert multiple rows
    	INSERT IGNORE INTO t1 SELECT * FROM t2;		- ignore errors
    REPLACE - works exactly like INSERT except that if a value exists for a PRIMARY KEY or a UNIQUE index, the old row is deleted and the new row is inserted. To use REPLACE, both the INSERT and DELETE privileges are needed for the table.

    SELECT
    	SELECT * FROM t1 LIMIT 1,10;		- limited rows (offset, rowcount)
    	SELECT * FROM t1 LIMIT 10 OFFSET 1;	- limited rows
    	SELECT col1 INTO @var1 FROM t1 WHERE col2 = 'x';	- store column value in a variable
    	SELECT SUM(c1='a') a_cnt, SUM(c1='b') b_cnt FROM t1;	- counts
    	SELECT * from t1 order by CAST(percentage AS DECIMAL(5,2)) DESC;	- order by with cast
    	SELECT * from t1 order by (c1 = 'Yes' AND c2 = 1) DESC;	- order by specific column values
    Subqueries
    	SELECT IF (EXISTS (SELECT * FROM t1 WHERE c1 = 1),1, 0);	- if exists
    	SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1  AND t2.c2 = 0 
    		AND NOT EXISTS (SELECT * FROM t1 WHERE c1 = t2.c1 AND c2 = 1);	- not exists
    	SELECT t1.* from (SELECT t2.col1, t3.col2 FROM t2, t3 where t2.c1 = t3.c2) t1;	- derived table 
    	SELECT t1.c1 from t1 where t1.c2 = (SELECT max(c2) FROM t2 where c1 = t1.c1);	- dependent subquery 
    	SELECT * from t1, (SELECT max(c1) FROM t1 group by c2) t2 where t1.c1 = t2.c1;	- find max value of c1 for each c2 value
    UPDATE
    	update t1, t2 set t1.c1 = t2.c1 where t1.c2 = t2.c2;
    Prepared statements (Dynamic SQL)

    MySQL supports server-side prepared statements using the efficient client/server binary protocol through client programming interfaces. An alternative SQL interface is also available based on the below statements.

    PREPARE - prepares a statement for execution
    EXECUTE - executes a prepared statement
    DEALLOCATE PREPARE - releases a prepared statement
    	SET @colname = CONCAT('day',DAY(CURRENT_DATE));
    	SET @query = CONCAT('SELECT count(*) FROM t1 where ', @colname,' = 0');
    	
    	PREPARE stmt FROM @query;
    	EXECUTE stmt;
    	DEALLOCATE PREPARE stmt;
    A prepared statement is specific to the session where it was created and if the session is terminated without deallocating it, the server deallocates it automatically.

    The variable max_prepared_stmt_count can be used to guard against too many prepared statements being created simultaneously. A value of 0 prevents the use of prepared statements.
    	show global variables like 'max_prepared_stmt_count';	- default 16382

    Functions

    Cast
    BINARY - converts an expression to a binary string
    	SELECT BINARY 'a' = 'A';  - returns 0
    CAST(expr as type)/CONVERT(expr,type) - cast an expression to the specified type
    	CONVERT('129291',UNSIGNED INTEGER)   - convert str to int
    	CONVERT(129291,CHAR(10))   - convert int to str
    CONVERT(expr USING transcoding_name) - converts data between different character sets
    	SELECT CONVERT('abc' USING utf8);
    Comparison
    COALESCE(list) - returns the first non-NULL value in the list, or NULL if there are no non-NULL values
    GREATEST (val1, val2..) - returns the largest argument
    ISNULL(expr) - returns 1 or 0
    LEAST (val1, val2...) - returns the smallest argument

    Control flow
    IF(expr1,expr2,expr3) - returns expr2 if expr1 is true, else expr3
    CASE - has two syntaxes
    	CASE var1 WHEN val1 THEN out1 WHEN val2 THEN out2 ELSE out3 END
    	
    	CASE WHEN cond1 THEN out1 WHEN cond2 THEN out2 ELSE out3 END
    	
    	SELECT * from t1 LEFT JOIN t2 ON CASE WHEN t1.c1=1 THEN t2.id= t3.id
    			   WHEN t1.c1=2 THEN t2.id= t4.id END  - join on case
    IFNULL (expr1,expr2) - returns expr1 if it is not null, else expr2
    NULLIF (expr1,expr2) - returns null if expr1 = expr2 is true, else returns expr1
    	SELECT NULLIF (1,1);	- returns 1
    Date
    CURDATE() - returns the current date
    CURRENT_TIMESTAMP() - returns the current date and time
    DATE(datetime) - extracts the date part of a datetime expression
    DATE_ADD/DATE_SUB - perform date arithmetic
    	DATE_ADD(NOW(),INTERVAL 2 DAY)
    DATE_FORMAT(date,format) - formats a date value as per the format string
    	DATE_FORMAT(NOW(),'%Y-%m-01')  - gets first day of current month
    	DATE_FORMAT(NOW(),'%Y-%m-31') - INTERVAL 1 MONTH   - get last day of prior month
    The specifiers that can be used in the format string are
    	%d	day of the month
    	%h/%H	hour(0-12)/hour(0-24)
    	%i	minutes
    	%m	month
    	%M	month name
    	%p	AM or PM
    	%s	seconds
    	%y/%Y	2-digit/4-digit year
    LAST_DAY(date) - returns the last day of the month or NULL if the argument is invalid
    	SELECT count(*) from t1 WHERE date1 BETWEEN DATE_FORMAT(NOW(),'%Y-%m-01 00:00:00') 
    		AND DATE_FORMAT(LAST_DAY(CURDATE()),'%Y-%m-%d 23:59:59');
    MONTH(date) - returns the month
    MONTHNAME(date) - returns the name of the month
    NOW() - returns the current date and time
    SEC_TO_TIME(secs) - converts seconds to HH:MM:SS time format
    	SEC_TO_TIME(2378)	-- '00:39:38'
    STR_TO_DATE(str,format) - takes in a string and returns a DATETIME, DATE or TIME value as per the format string
    	STR_TO_DATE(9, '%m')	- '0000-09-00'
    	STR_TO_DATE ('15.04.2011','%d.%m.%Y')	- '2011-04-15'
    SYSDATE() - returns the time at which it executes
    	SELECT SYSDATE(6); - returns time with a fractional seconds precision of 6
    TIME() - extracts the time part of a datetime expression
    TIME_TO_SEC(time) - converts time to seconds
    TIMESTAMPDIFF() - returns difference between two dates
    	SELECT TIMESTAMPDIFF(SECOND,'2016-01-01','2016-05-01 12:05:55');
    	SELECT CONCAT(TRUNCATE(time_ms/(1000*60*60*24),0), 'd ', CAST((time_ms/(1000*60*60)%24) AS UNSIGNED INTEGER), 'h ',
    		CAST((time_ms/(1000*60)%60) AS UNSIGNED INTEGER), 'm ');   - convert millisecs to day/hour/mins
    WEEKDAY(date) - returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday)
    YEAR(date) - returns the year

    Information
    CHARSET(expr) - returns the character set of the argument
    COLLATION(str) - returns the collation of the string argument
    LAST_INSERT_ID() - value of the AUTOINCREMENT column for the last INSERT
    	SELECT CONNECTION_ID();	- connection ID (thread ID) for the connection
    	SELECT CURRENT_USER();	- authenticated user name and host name
    	SELECT DATABASE();	- current database name
    	SELECT VERSION();	- MySQL server version
    	SELECT USER();		- user name and host name provided by the client
    Mathematical
    ABS(x) - returns the absolute (positive) value of x
    CEIL(x) - returns the smallest integer not less than x
    FLOOR(x) - returns the largest integer not greater than x
    RAND() - returns a random floating-point value between 0 and 1.0
    	SELECT FLOOR(i + (RAND() * j-i));	- returns a random number between i and j
    ROUND(x,d) - rounds x to d decimal places
    TRUNCATE(x,d) - truncates to d decimal places. If d is 0, the result has no decimal point. d = negative causes d digits left of the decimal point of x to become zero

    String
    CHAR_LENGTH(str)/CHARACTER_LENGTH(str) - returns the length of a string, measured in code points. A multi-byte character counts as a single code point. For a string containing two 3-byte characters, CHAR_LENGTH() returns 2 whereas LENGTH() returns 6
    CONCAT - concatenate strings
    	SELECT CONCAT('drop table ', table_name,';') FROM information_schema.tables where table_name like 'tmp%' AND table_schema = 'db1';
    CONCAT_WS(separator,str1,str2..) - concatenate strings with a separator added between
    ENCRYPT(str) - encrypts using the Unix crypt() system call and returns a binary string
    FIELD(str,s1,s2,s3,...) - returns the index (position) of str in the s1, s2, s3 list, 0 if str is not found
    FORMAT(x,d [,locale]) - Formats the number x to a format like 'n,nnn,nnn.nn', rounded to d decimal places, and returns the result as a string. If d is 0, the result has no fractional portion. Locale by default is en_US.
    	SELECT FORMAT(1712332.123456, 4);   -> '1,712,332.1235'
    GROUP_CONCAT - returns a string result with the concatenated non-NULL values from a group. The result is truncated to the length given by the group_concat_max_len system variable (default = 1024)
    	SELECT player, GROUP_CONCAT(DISTINCT score ORDER BY score DESC SEPARATOR ' ') FROM scores GROUP BY player;
    	
    	SHOW GLOBAL VARIABLES LIKE 'group_concat_max_len';
    	SET SESSION group_concat_max_len = 50000;
    HEX(str) - returns a hexadecimal string representation of str
    INSTR(str,substr) - returns the position of the first occurrence of substring substr in string str, same as the two-argument form of LOCATE(), except that the order of the arguments is reversed
    LENGTH(str) - returns no. of bytes in string
    LOAD_FILE(file) - reads the file and returns contents as a string
    	UPDATE t SET blob_col=LOAD_FILE('/tmp/picture') WHERE id=1;
    LOCATE(substr, str [,pos]) - returns the position of the first occurrence of substring substr in string str starting at position pos. Returns 0 if substr is not in str
    LPAD/RPAD(str,len,padstr) - returns the string str, left/right-padded with the string padstr to a length of len characters
    	LPAD('3',2,'00') -- returns '03'
    SOUNDEX(str) - returns a soundex string
    	SELECT * from emp where soundex(first_name) = soundex('Jon');
    SPACE(n) - returns a string of n spaces
    SUBSTR(str,pos,len) - returns a portion of a string. A -ve value for pos implies pos characters from the end of the string
    SUBSTRING_INDEX(str,delim,count) - returns the substring from string str before count occurrences of the delimiter delim.
    	SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);  -> 'www.mysql'
    	SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);  -> 'mysql.com'
    TO_BASE64(str) - converts a string to base-64 encoded form
    UPPER(str)/LOWER(str) - changes all characters to upper/lower case according to the current character set mapping (default utf8mb4)

    Regular Expressions
    	SELECT c1 from t1 where c1 REGEXP '[0-9]';		- find numbers        
    	SELECT c1 FROM t1 WHERE c1 REGEXP '[^0-9]';		- without numbers	
    	SELECT c1 from t1 where c1 REGEXP '^[0-9]';		- find numbers in beginning        
    	SELECT c1 from t1 where c1 REGEXP '[0-9]$';		- find numbers at end
    	SELECT c1 FROM t1 WHERE c1 REGEXP '[A-Za-z]';		- find characters
    	SELECT c1 FROM t1 WHERE c1 REGEXP '[A-Za-z]{2,}';	- find characters in sequence
    	SELECT c1 from t1 where c1 NOT REGEXP '[0-9!%#@*&^?$~,.`[.hyphen.][.right-square-bracket.]
    			[.slash.][.semicolon.][.less-than-sign.][.greater-than-sign.][.equals-sign.][.left-square-bracket.]]';	- validate name
    Others
    SLEEP(s) - pauses for s seconds
    	SELECT SLEEP(5);	- returns 0
    	DO SLEEP(5);		- no output
    UUID() - returns a UUID

    Comments

    MySQL server supports three comment styles:
  • From a # character to the end of the line
  • From a -- sequence to the end of the line
  • From a /* sequence to the following */ sequence, as in the C language

    MySQL supports some variants of C-style comments. These enable writing code that includes MySQL extensions, but is still portable.
    	/*! MySQL-specific code */
    If a version number is added after the ! character, the syntax within the comment is executed only if the MySQL version is greater than or equal to the specified version number
    	CREATE TABLE t1(a INT, KEY (a)) /*!50110 KEY_BLOCK_SIZE=1024 */;	- executed only by version 5.1.10 or higher

    User-defined variables

    A value can be stored in a user-defined variable in one statement and referred to in another statement, enabling passing of values from one statement to another. User-defined variables are session specific and can only be seen and used by the client defining them, but a user with access to the performance_schema.user_variables_by_thread table can see all user variables for all sessions. All variables for a client session are automatically freed when the client exits.

    User variables are written as @var_name, where var_name consists of alphanumeric characters, ., _ and $. A user variable name can contain other characters if quoted as a string or identifier (e.g @'my-var', @"my-var", or @`my-var`). User variable names are not case-sensitive and have a maximum length of 64 characters.

    A user-defined variable can be set by issuing a SET statement. Either = or := can be used as the assignment operator.
    	SET @a = 1; SET @b := 2; SELECT @c := 3;	- assigning values 
    
    	SET @curRank = 0; SELECT name, age, @curRank := @curRank + 1 AS rank FROM t1 ORDER BY age;	- ranking rows
    
    	SELECT id, group_id, if(@grp <> group_id, @rank := @rank + 1, @rank) as rank, @grp := group_id
    				FROM t1, (SELECT @rank := 0, @grp := 0) r order by group_id;	- rank by group
    User variables can be employed to remember results without having to store them in temporary variables in the client. For e.g, to find the items with the highest and lowest price
    	SELECT @min_price:=MIN(price), @max_price:=MAX(price) FROM items;
    	SELECT * FROM items WHERE price=@min_price OR price=@max_price;

    Back



    SERVER ADMINISTRATION

    Installing/upgrading MySQL

    MySQL editions

    MySQL Community Edition is the freely downloadable version. Commercial editions available are: Standard, Enterprise and Cluster Carrier Grade(CGE).

    The Enterprise edition includes features like Enterprise backup, Transparent Data Encryption(TDE), Enterprise monitor and Oracle MySQL cloud service. MySQL Cluster is the distributed database combining linear scalability and high availability providing in-memory real-time access with transactional consistency across partitioned and distributed datasets.

    Installing MySQL

    MySQL can be installed using a set of binary distributions in the form of .tar.gz files or from the source code. Building MySQL from the source code enables customizing of build parameters, compiler optimizations and installation location.

    After downloading a MySQL package, it must be ensured that its MD5 checksum matches the one provided on the MySQL download pages. Each package has an individual checksum that can be verified against the package that was downloaded. Each OS offers its own version of tools for checking the MD5 checksum.
    	-- Linux
    	$> md5sum mysql-standard-8.0.28-linux-i686.tar.gz
    	aaab65abbec64d5e907dcd41b8699945  mysql-standard-8.0.28-linux-i686.tar.gz
    	
    	-- Windows
    	$> md5.exe mysql-installer-community-8.0.28.msi
    	aaab65abbec64d5e907dcd41b8699945  mysql-installer-community-8.0.28.msi
    Upgrading MySQL

    In-place upgrade - involves shutting down the server, replacing the old MySQL binaries or packages with the new ones and restarting MySQL on the existing data directory and running mysql_upgrade to update data structures.

    Before the upgrade, MySQL should be configured to perform a slow shutdown
    	SET GLOBAL innodb_fast_shutdown=0;
    With a slow shutdown, InnoDB performs a full purge and change buffer merge before shutting down, which ensures that data files are fully prepared in case of file format differences between releases.

    Logical upgrade - involves exporting existing data from the old version using mysqldump, installing the new MySQL version and loading the dump file into the new version and running mysql_upgrade.

    MySQL source files

    btr0cur.cc - The index tree cursor. All changes that row operations make to a B-tree go through this module. Undo log records are written for every modify or insert of a clustered index record
    btr0sea.cc - The index tree adaptive search
    buf0buf.cc - The database buffer pool
    buf0flu.cc - The buffer pool dirty page write and flush algorithm
    buf0lru.cc - The buffer pool replacement algorithm
    dict0dict.cc - Data dictionary system
    fil0fil.cc - The tablespace memory cache
    fsp0fsp.cc - File space management
    log0log.cc - Redo log
    mtr0log.cc - Mini-transaction log routines
    mtr0mtr.cc - Mini-transaction buffer
    row0ins.cc - Insert a row in a table
    srv0srv.cc - The database server main program


    MySQL startup/shutdown

    When MySQL server starts, it listens for network connections from client programs and manages access to databases on behalf of those clients.
    	-- Linux
    	sudo /etc/init.d/mysqld start		
    	sudo /etc/init.d/mysqld stop
    	sudo /etc/init.d/mysqld restart
    
    	-- Windows
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld" --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.7\my.ini"  - start server
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqlshow" -u root -p mysql    - shows tables in mysql db
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqladmin" -u root -p version status proc  - shows server info
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqladmin" -u root -p shutdown         - stop

    If innodb_fast_shutdown is 0, InnoDB does a slow shutdown, a full purge and a change buffer merge before shutting down. The slow shutdown can take minutes or even hours when substantial amounts of data are still buffered. The slow shutdown technique should be used before upgrading or downgrading between MySQL major releases, so that all data files are fully prepared in case the upgrade process updates the file format.

    If the value is 1 (the default), InnoDB skips those operations at shutdown, a process known as a fast shutdown.

    If the value is 2, InnoDB flushes its logs and shuts down cold, as if MySQL had crashed. No committed transactions are lost but the crash recovery operation makes the next startup take longer. It should be used in emergency or troubleshooting situations for the fastest shutdown if data is at risk of corruption.
    	SHOW GLOBAL VARIABLES like 'innodb_fast_shutdown'; - the InnoDB shutdown mode

    The MySQL server shutdown process takes place as follows

  • The shutdown process is initiated by a SHUTDOWN command or a signal from the OS
  • The server creates a shutdown thread, if shutdown was requested by a client. If shutdown is the result of receiving a SIGTERM signal, the signal thread might handle shutdown itself or it might create a separate thread to do so
  • The server stops accepting new connections by closing the handlers for the network interfaces to which it listens for connections - the TCP/IP port, the Unix socket file, the Windows named pipe and shared memory on Windows
  • The server terminates current activity. For each thread associated with a client connection, the server breaks the connection and marks the thread as killed. For threads that have an open transaction, the transaction is rolled back

    If the server is a replication master, it treats threads associated with currently connected slaves like other client threads and each one is marked as killed and exits when it next checks its state. If the server is a slave, it stops the I/O and SQL threads, if they are active, before marking client threads as killed. The SQL thread is permitted to finish its current statement (to avoid causing replication problems) and then stopped. If the SQL thread is in the middle of a transaction, the server waits until the current replication event group has finished executing, or until the user issues a KILL QUERY or KILL CONNECTION statement

  • The server shuts down or closes storage engines, flushes the table cache and closes all open tables. InnoDB flushes its buffer pool to disk (unless innodb_fast_shutdown is 2), writes the current LSN to the tablespace and terminates its own internal threads
  • The server exits returning one of the following exit codes
    	0 = successful termination (no restart done)
    	1 = unsuccessful termination (no restart done)
    	2 = unsuccessful termination (restart done)

    Running multiple instances on a machine The primary resource managed by a MySQL instance is the data directory. So each instance should use a different data directory specified using the --datadir option.
    	datadir=C:/ProgramData/MySQL/MySQL Server 5.7\Data			- inst1
    	datadir=C:/ProgramData/MySQL/MySQL Server 5.7\Data-slave		- inst2
    Each instance should have a distinct port number for TCP/IP connections. Alternatively, if the host has multiple network addresses, --bind-address can be used to cause each server to listen to a different address.
    	port=3306			- inst1
    	port=3307			- inst2
    The instances can be started using their own option files and shut down separately.
    	-- inst1
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.7\my.ini" 				
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin>mysqladmin" -u root -p --port=3306 shutdown
    	-- inst2
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld.exe" --defaults-file="C:\ProgramData\MySQL\MySQL Server 5.7\my-slave.ini" 				
    	"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqladmin" -u root -p --port=3307 shutdown

    Server configuration

    Server variables

    The MySQL server maintains system variables that configure its operation. The default values of the variables can be changed at server startup using command-line options or configuration files or dynamically changed at runtime by the SET statement globally (effective till the next restart of the server) or for the current session. Setting the global value of a system variable requires the SYSTEM_VARIABLES_ADMIN/SUPER privilege. Setting the session system variable requires no special privileges and can be done by any user.
    	SHOW GLOBAL VARIABLES;	- list all global system variables
    
    	SHOW GLOBAL VARIABLES LIKE '%version%';  - mysql version info
    	SHOW GLOBAL VARIABLES LIKE 'server%';
    		server_id	- used in replication to uniquely identify master and slave servers
    		server_uuid	- true uuid of server 
    	SHOW GLOBAL VARIABLES like '%time_zone';	
    		system_time_zone	- server system time zone
    		time_zone	- used to initialize the time zone for each client that connects, default=SYSTEM (system_time_zone)
    Certain global system variables can also be persisted to the mysqld-auto.cnf file in the data directory so that they apply across server restarts.
    	SET PERSIST max_connections=1000;
    	SET PERSIST_ONLY table_open_cache=8192;	- persist a variable without setting the runtime value
    	RESET PERSIST max_connections;		- remove a persisted variable from mysqld-auto.cnf
    	RESET PERSIST;				- remove all persisted variables
    The performance_schema persisted_variables table provides an SQL interface to the mysqld-auto.cnf file.
    	SELECT * FROM performance_schema.persisted_variables;
    The MySQL server also maintains status variables that provide information about its operation. The global variables aggregate the values for all connections and the session variables show the values for the current connection.
    	SHOW GLOBAL STATUS;	- list all global status variables
    	SHOW GLOBAL STATUS like 'uptime';  -  number of seconds that the server has been up

    Server SQL modes

    The MySQL server can operate in different SQL modes and can apply these modes differently for different clients, depending on the value of the sql_mode system variable.
    	SHOW GLOBAL VARIABLES like 'sql_mode';
    ONLY_FULL_GROUP_BY - reject queries that refer to non-aggregated columns that are not in the GROUP BY clause
    NO_ENGINE_SUBSTITUTION - control automatic substitution of the default storage engine when CREATE/ALTER TABLE statement specifies an unavailable storage engine
    NO_ZERO_DATE - does not permit '0000-00-00' as a valid date
    STRICT_ALL_TABLES - enable strict SQL mode for all storage engines
    STRICT_TRANS_TABLES - enable strict SQL mode for transactional storage engines and when possible for non-transactional engines

    Strict SQL mode

    Strict mode controls how MySQL handles invalid or missing values in statements such as INSERT or UPDATE. Strict SQL mode is in effect if either STRICT_ALL_TABLES or STRICT_TRANS_TABLES is enabled. If strict mode is not in effect, MySQL inserts adjusted values for invalid or missing values and produces warnings. Strict SQL mode causes an error on division by zero and does not permit '0000-00-00' as a valid date.


    Character set and collation

    Every server, database, table and character column has a character set and a collation. If they are not specified at table create time, the default character set and collation are used.
    	SHOW CHARACTER SET;  	- available character sets and their default collation
    	SHOW COLLATION WHERE charset = 'latin1';
    The server character set and collation are used as default values if the database character set and collation are not specified in CREATE DATABASE statements and have no other purpose. The CREATE/ALTER DATABASE statements have optional clauses for specifying the database character set and collation.
    	CREATE DATABASE db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    	ALTER DATABASE db1 CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
    The character_set_database and collation_database system variables show character set and collation for the default database. The server sets these variables whenever the default database changes. If there is no default database, the variables have the same value as character_set_server and collation_server.
    	show global variables like 'character_set%';
    		character_set_server	- default server character set
    		character_set_database	- character set used by the default database
    		character_sets_dir	- directory where character sets are installed
    
    	show global variables like 'collation_%';
    		collation_server	- default server collation
    		collation_database	- collation used by the default database
    For CREATE TABLE statements, the database character set and collation are used as default values for table definitions if the table character set and collation are not specified.
    	CREATE TABLE t1(col_list) CHARACTER SET utf8 COLLATE utf8_bin;
    	ALTER TABLE t1 CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;	- change table character set and collation
    	ALTER TABLE t1 MODIFY COLUMN c1 varchar(255) CHARSET utf8 COLLATE utf8_unicode_ci;	- change column character set and collation
    	SELECT t1.* from t1, t2 WHERE t1.col1 COLLATE utf8_unicode_ci = t2.col2;	-  override collation in query
    Opening and closing tables

    MySQL is multi-threaded, so many clients issue queries for a given table simultaneously. To minimize the problem with multiple client sessions having different states on the same table, the table is opened independently by each concurrent session, which uses additional memory but normally increases performance.

    The cache of open tables is kept at a level of table_open_cache entries. The table_open_cache and max_connections system variables affect the maximum number of files the server keeps open. If one or both of these values are increased, it may run up against a limit imposed by the OS on the per-process number of open file descriptors. Many OSs permit the open-files limit to be increased.

    table_open_cache is related to max_connections. For e.g, for 200 concurrent running connections, a table cache size of at least 200 * N can be specified, where N is the maximum number of tables per join in any of the queries executed. Some extra file descriptors must also be reserved for temporary tables and files. The effective value of table_open_cache is the greater of (the effective value of open_files_limit - 10 - the effective value of max_connections / 2) and 400.

    It must be ensured that the OS can handle the number of open file descriptors implied by the table_open_cache setting. If table_open_cache is set too high, MySQL may run out of file descriptors and exhibit symptoms such as refusing connections or failing to perform queries. If the opened_tables status variable is high or if queries are seen waiting in 'opening tables' state, then it may be prudent to increase table_open_cache.

    The table_definition_cache variable specifies the number of table definitions that can be stored in the definition cache. If a large number of tables are used, a large table definition cache can be created to speed up opening of tables. The table definition cache takes less space and does not use file descriptors, unlike the normal table cache. The minimum value is 400. The default value is based on the formula MIN(400 + table_open_cache / 2, 2000), capped to a limit of 2000.
    	SHOW GLOBAL VARIABLES LIKE '%table%';
    		table_open_cache	- open tables for all threads
    		table_open_cache_instances	- the number of open tables cache instances
    		table_definition_cache	- table definitions that can be stored in the definition cache (default -1, signifies autosizing)
    	
    	SHOW GLOBAL STATUS like '%table%';
    		open_tables		- tables that are open
    		opened_tables		- tables that have been opened since server startup
    		open_table_definitions	- open table definitions
    		opened_table_definitions - table definitions opened since server startup
    The open_files_limit variable specifies the number of file descriptors available to mysqld from the OS (LimitNOFILE in Linux). The runtime value of this variable is the real value permitted by the system and might differ from the value specified at startup. The effective open_files_limit value is based on the value specified at startup and the values of max_connections and table_open_cache.
    	SHOW GLOBAL VARIABLES like 'open_files_limit';	- the number of files that the OS permits mysqld to open
    If the file descriptors allocated to MySQL are not enough, 'Too many open files' or 'File table overflow' errors may result.

    The innodb_open_files variable specifies the maximum number of .ibd files that MySQL can keep open at one time. The default value is the higher of 300 and table_open_cache. The file descriptors used for .ibd files (innodb tables) are independent of those specified by open_files_limit and do not affect the operation of the table cache.
    	SHOW GLOBAL VARIABLES like 'innodb_open_files';

    Connection management

    The MySQL server listens on one or more network sockets for TCP/IP connections. Each socket is bound to one address, but it is possible for an address to map onto multiple network interfaces. The bind_address variable needs to be set at server startup to specify how the server should listen for TCP/IP connections.
    	SHOW GLOBAL VARIABLES like 'bind_address';
    If bind_address is specified, it accepts a list of one or more address values, each of which may specify a single non-wildcard IP address or host name. Each address may include a network namespace specifier. If only one address is specified, it may make use of one of the wildcard address formats that permit listening on multiple network interfaces (*, 0.0.0.0 or ::). When multiple addresses separated by commas are listed, each value must specify a single non-wildcard IP address (either IPv4 or IPv6) or a host name, and wildcard address formats (*, 0.0.0.0 or ::) are not allowed.

    IP addresses can be specified as IPv4 or IPv6 addresses. For any value that is a host name, the server resolves the name to an IP address and binds to that address. If a host name resolves to multiple IP addresses, the server uses the first IPv4 address if there are any, or the first IPv6 address otherwise.

    The server treats different types of addresses as follows:
  • If the address is *, the server accepts TCP/IP connections on all server host IPv4 interfaces, and if the server host supports IPv6, on all IPv6 interfaces. It is the default and permits both IPv4 and IPv6 connections on all server interfaces
  • If the address is 0.0.0.0, the server accepts TCP/IP connections on all server host IPv4 interfaces
  • If the address is ::, the server accepts TCP/IP connections on all server host IPv4 and IPv6 interfaces
  • If the address is an IPv4-mapped address, the server accepts TCP/IP connections for that address, in either IPv4 or IPv6 format. For e.g if the server is bound to ::ffff:127.0.0.1, clients can connect using --host=127.0.0.1 or --host=::ffff:127.0.0.1
  • If the address is a regular IPv4 or IPv6 address (such as 127.0.0.1 or ::1), the server accepts TCP/IP connections only for that IPv4 or IPv6 address

    Connection manager threads

    Connection manager threads associate each client connection with a thread dedicated to it that handles authentication and request processing for that connection. Manager threads consult the thread cache to see whether it contains a thread that can be used for the connection. When a connection ends, its thread is returned to the thread cache if the cache is not full.
    	SHOW GLOBAL VARIABLES LIKE 'thread_cache_size';	- how many threads the server should cache for reuse
    The default value of thread_cache_size is calculated by (max_connections / 100) + 8, capped to a maximum of 100.

    If the server sees hundreds of connections per second, thread_cache_size should be set high enough so that most new connections use cached threads. The efficiency of the thread cache can be seen by examining the difference between the connections and threads_created status variables.
    	SHOW GLOBAL STATUS LIKE 'threads_%';
    		threads_cached		- threads in cache
    		threads_created		- threads created apart from cache, if high thread_cache_size can be increased
    		threads_connected	- current connections
    		threads_running		- threads not sleeping
    Each client thread is associated with a connection buffer and result buffer. Both begin with a size given by net_buffer_length but are dynamically enlarged up to max_allowed_packet bytes as needed. The result buffer shrinks to net_buffer_length after each SQL statement.
    	SHOW GLOBAL VARIABLES LIKE 'net_buffer_length';		- default 16KB, maximum 1 MB
    	SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet';	- maximum size of the communication buffer between server and client
    The max_connections system variable controls the maximum number of clients the server permits to connect simultaneously. If the server refuses a connection because the limit is reached, it increments the Connection_errors_max_connections status variable.
    	SHOW GLOBAL VARIABLES like '%connections%';
    		max_connections		- maximum simultaneous client connections
    		max_user_connections	- maximum simultaneous connections permitted to a user account (default = 0, no limit)
    	SHOW GLOBAL STATUS like '%connection%';
    		connections		- number of connection attempts (successful or not)
    		max_used_connections	- maximum connections that have been in use simultaneously since the server started
    		connection_errors_max_connections	- number of connections refused because max_connections was reached
    mysqld actually permits max_connections + 1 client connections, the extra connection being reserved for use by accounts that have the CONNECTION_ADMIN or SUPER privilege to connect and diagnose problems.

    Increasing the max_connections value increases the number of file descriptors that mysqld requires and if the required descriptors are not available, the server reduces the value of max_connections. Increasing the open_files_limit system variable may be necessary, which may also require raising the OS limit on how many file descriptors can be used by MySQL.
    	SHOW GLOBAL VARIABLES like '%timeout%';
    		connect_timeout		- number of seconds that mysqld waits for a connect packet before responding with Bad handshake (default 10)
    		net_read_timeout	- number of seconds to wait for more data from a connection before aborting the read (default 30)
    		net_write_timeout	- number of seconds to wait for a block to be written to a connection before aborting the write (default 60)
    Host cache

    The MySQL server maintains an in-memory host cache that contains information about clients' IP address, host name and error information. The performance_schema.host_cache table exposes the contents of the host cache. The host cache is enabled by default and its size is controlled by the host_cache_size variable.

    The server uses the host cache only for non-localhost TCP connections. It is not used for TCP connections established using a loopback interface address (e.g 127.0.0.1 or ::1), or for connections established using a Unix socket file, named pipe or shared memory.

    By caching the results of IP-to-host name lookups, the server avoids doing a DNS lookup for each client connection and only needs to perform a lookup only for the first connection from that host. The cache also contains information about errors that occur during the client connection process and if too many of these occur successively from a given host without a successful connection, the server blocks further connections from that host. The max_connect_errors variable determines the permitted number of successive errors before blocking occurs. Flushing the host cache unblocks any blocked hosts.
    	SHOW GLOBAL VARIABLES like 'host_cache_size';
    	SHOW GLOBAL VARIABLES like 'max_connect_errors';
    Closing idle connections

    On thread startup, the session wait_timeout value is initialized from the global wait_timeout or interactive_timeout value, depending on the type of client as defined by the CLIENT_INTERACTIVE connect option to mysql_real_connect().
    	SHOW GLOBAL VARIABLES like '%timeout%';
    		interactive_timeout	- number of seconds the server waits for activity on an interactive connection before closing it (default 28800)
    		wait_timeout		- number of seconds waited for activity on a non-interactive connection before closing it (default 28800)
    Connection character sets and collations

    Every client has session-specific connection-related character set and collation system variables which are initialized at connect time, but can be changed within the session.
    	show global variables like 'char%';
    		character_set_client	- character set for statements sent from the client
    		character_set_connection	- character set used for literals specified without an introducer and for number-to-string conversion
    		character_set_results	- character set in which the server sends query results to the client
    The server converts statements (without introducers) sent by the client from character_set_client to character_set_connection.

    When a client connects to the server, it indicates which character set it wants to use for communication with the server. Actually, the client indicates the default collation for that character set from which the server can determine the character set and set the character_set_client, character_set_results, character_set_connection and collation_connection variables for the session. In effect, the server performs the equivalent of a SET NAMES operation.

    If the server does not support the requested character set or collation, it falls back to using the server character set and collation to configure the connection.

    Each client supports a --default-character-set option, which enables users to specify the character set explicitly to override whatever default the client otherwise determines.
    	[mysql]
    	default-character-set=utf8
    collation_connection is important for comparisons of literal strings. For comparisons of strings with column values, collation_connection does not matter because columns have their own collation, which has a higher precedence.
    	show global variables like 'collation%';
    		collation_connection	- collation of the connection character set

    MySQL server plugins

    MySQL supports a plugin API that enables creation of server components. Plugins can be loaded at server startup or loaded and unloaded at runtime without restarting the server. The components supported by this interface include storage engines, INFORMATION_SCHEMA tables, full-text parser plugins, server extensions stc.

    Installing plugins

    Before a server plugin can be used, it must be installed using one of the following methods
  • Built-in plugins - a built-in plugin is known by the server automatically and the server enables the plugin at startup
  • Plugins registered in the mysql.plugin system table - The mysql.plugin table serves as a registry of plugins (other than built-in plugins, which need not be registered). At startup, the server loads each plugin listed in the table.
    	select * from mysql.plugin;
  • Plugins named with command-line options - a plugin located in a plugin library file can be loaded at server startup with the --plugin-load, --plugin-load-add or --early-plugin-load option
  • Plugins installed with the INSTALL PLUGIN statement - a plugin located in a plugin library file can be loaded at runtime with the INSTALL PLUGIN statement. The statement also registers the plugin in the mysql.plugin table to cause the server to load it on subsequent restarts. It requires the INSERT privilege for the mysql.plugin system table.
    	INSTALL PLUGIN plugin_name SONAME 'shared_library_name';
    
    	SHOW GLOBAL VARIABLES LIKE 'plugin_dir';
    Shared_library_name is the name of the shared library that contains the plugin code and it must be located in the plugin directory (the directory named by the plugin_dir system variable). The library must be in the plugin directory itself, not in a subdirectory.

    Loading plugins

    Server plugins must be loaded into the server before they can be used. MySQL supports plugin loading at server startup and runtime, controlling the activation state of loaded plugins and unloading them at runtime.

    When a plugin is loaded, information about it is available from the INFORMATION_SCHEMA.PLUGINS table and the SHOW PLUGINS statement.

    To be usable by the server, the plugin library file must be located in the MySQL plugin directory. The --early-plugin-load option is used to load the plugin by naming the library file that contains it.
    	SHOW PLUGINS;		- shows installed plugins
    	SELECT * from information_schema.plugins;
    
    	[mysqld]
    	early-plugin-load=keyring_file.so
    Uninstalling plugins

    The UNINSTALL PLUGIN statement disables and uninstalls a plugin known to the server at runtime. It unloads the plugin and removes it from the mysql.plugin table, if it is registered there, and the server does not load the plugin automatically for subsequent restarts. The UNINSTALL PLUGIN statement requires the DELETE privilege for the mysql.plugin table.


    Monitoring the server

    Information_schema tables

    InnoDB INFORMATION_SCHEMA tables provide metadata, status information and statistics about the InnoDB storage engine and can be used to monitor ongoing InnoDB activity.
    	SELECT * FROM information_schema.INNODB_BUFFER_POOL_STATS \G	- provides buffer pool status info
    	SELECT * FROM information_schema.INNODB_METRICS \G	- stores innoDB performance and resource-related counters
    The PROCESSLIST table provides information about which threads are running.
    	select * from information_schema.processlist;	- shows running threads
    	SHOW FULL PROCESSLIST;	- equivalent to above
    Performance Schema

    The performance schema is a feature for monitoring MySQL Server execution at a low level during runtime and is implemented using the PERFORMANCE_SCHEMA storage engine and the performance_schema database.

    The performance schema monitors server events and an event is anything the server does that takes time and has been instrumented so timing information can be collected. The PERFORMANCE_SCHEMA storage engine collects event data using instrumentation points in server source code and stores them in in-memory tables in the performance_schema database. The tables are discarded at server shutdown and repopulated at startup.
    	SHOW GLOBAL variables LIKE 'performance_schema';   - ON(default)
    The internal operation and memory requirements of the Performance Schema can be inspected by
    	SHOW ENGINE PERFORMANCE_SCHEMA STATUS;
    Name values consist of two parts, an internal buffer and a buffer attribute.
  • an internal buffer that is not exposed as a table is named within parentheses. Examples: (pfs_cond_class).row_size, (pfs_mutex_class).memory
  • an internal buffer that is exposed as a table in the performance_schema database is named after the table, without parentheses. Examples: events_waits_history.row_size, mutex_instances.row_count
  • a value that applies to the Performance Schema as a whole begins with performance_schema. Example: performance_schema.memory

    Buffer attributes have these meanings
  • row_size is the size of the internal record used by the implementation, such as the size of a row in a table. row_size values cannot be changed
  • row_count is the number of internal records, such as the number of rows in a table. row_count values can be changed using Performance Schema configuration options
  • for a table, tbl_name.memory is the product of row_size and row_count. For the Performance Schema as a whole, performance_schema.memory is the sum of all the memory used (the sum of all other memory values)

    Performance schema tables

    data_locks - shows data locks held and requested
    	SELECT * FROM performance_schema.data_locks \G
    data_lock_waits - shows locks requested that are being blocked by locks held
    	SELECT * FROM performance_schema.data_lock_waits \G
    	
    	SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id,
    	b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query 
    	FROM performance_schema.data_lock_waits w 
    	INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id 
    	INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id \G
    events_statements_current - one row per thread showing the current status of the thread's most recent monitored statement event Columns:
    event_name - the name of the instrument (from the setup_instruments table) from which the event was collected
    source - name of the source file containing the instrumented code that produced the event and the line number
    timer_start, timer_end, timer_wait - timing of the event in picoseconds (10-12)
    sql_text - text of the sql statement
    	select * from performance_schema.events_statements_current where timer_wait > 1000000000;  - timed more than 1 ms
    mutex_instances - lists all the mutexes seen by the performance_schema while the server executes Columns:
    name - the instrument name associated with the mutex
    object_instance_begin - the address in memory of the instrumented mutex
    locked_by_thread_id - when a thread currently has a mutex locked, the thread_id of the locking thread, else NULL
    	select * from performance_schema.mutex_instances;
    metadata_locks - metadata lock information Columns:
    object_type - the type of lock
    object_name - the name of the object
    owner_thread_id - thread requesting the lock
    	select * from performance_schema.metadata_locks;
    threads - The threads table has a row with information for each existing server thread and the rows are removed when threads end. For a thread associated with a client session, removal occurs when the session ends.

    The columns with names having a prefix of processlist_ provide information similar to the information_schema.processlist table or the SHOW PROCESSLIST statement. Access to threads does not require a mutex and has minimal impact on server performance while information_schema.processlist and SHOW PROCESSLIST require a mutex. The threads table includes background threads and also provides additional information for each thread. Columns:
    thread_id - unique thread identifier
    name - the name associated with the thread instrumentation code in the server thread/sql/one_connection - user connection
    thread/sql/main - main() function of the server
    type - FOREGROUND (user connection threads) or BACKGROUND (internal system threads)
    processlist_id - id displayed in the processlist table
    processlist_command - For foreground threads, the type of command the thread is executing on behalf of the client or Sleep (idle session)
    	Thread command values:
    	Binlog Dump - thread on a master for sending binary logs to slave
    	Daemon - internal server thread, not servicing a client connection
    	Processlist - the thread is producing info about server threads
    	Query - thread is executing a statement
    	Sleep - waiting for the client to send a statement
    processlist_state - thread state
    	General thread states:
    	cleaning up - The thread has processed one command and is preparing to free memory and reset certain state variables
    	closing tables - The thread is flushing the changed table data to disk and closing the used tables. This should be a fast 
    		operation unless the disk is full or heavily used
    	converting HEAP to ondisk - The thread is converting an internal temporary table from a MEMORY table to an on-disk table
    	copy to tmp table - The thread is processing an ALTER TABLE statement
    	Copying to tmp table - The server is copying to a temporary table in memory
    	Copying to tmp table on disk - The temporary result set has become too large and the thread is changing the temporary table 
    		from in-memory to disk-based format to save memory
    	Creating sort index - The thread is processing a SELECT that is resolved using an internal temporary table
    	freeing items  - command executed, usually followed by 'cleaning up'
    	init - occurs before the initialization of ALTER TABLE/SELECT/INSERT/UPDATE/DELETE statements. Actions taken by the server include 
    		flushing the binary log and the InnoDB log
    	Killed - A Kill statement has been issued to the thread and it should abort next time it checks the kill flag
    	Opening tables - The thread is trying to open a table. It should be a very fast operation unless something is preventing it
    	optimizing - performing initial optimizations for a query
    	preparing - occurs during query optimization
    	query end - occurs after processing a query but before the freeing items state
    	removing tmp table - The thread is removing an internal temporary table after processing a SELECT statement
    	Rolling back - rolling back a transaction
    	Searching rows for update - The thread is doing a first phase to find all matching rows before updating them. This has to be done if
    		the UPDATE is changing the index that is used to find the involved rows
    	Sending data - The thread is reading and processing rows for a SELECT statement, and sending data to the client
    	statistics - the server is calculating statistics to develop a query execution plan
    	System Lock - the thread has called mysql_lock_tables(). It is a general state that can occur for many reasons. For e.g, the thread is 
    		going to request or is waiting for an internal or external system lock for the table. This can occur when InnoDB waits for a 
    		table-level lock during execution of LOCK TABLES
    	updating reference tables - executing the second part of a multiple-table update and updating the matched rows from the other tables
    	waiting for handler commit - The thread is waiting for a transaction to commit versus other parts of query processing
    	Waiting for table flush - The thread is executing FLUSH TABLES and is waiting for all threads to close their tables
    	Waiting for table level lock -  Waiting for a table lock or a database dump is being performed
    	Waiting for table metadata lock - waiting to obtain a metadata lock
    processlist_time - time the thread has been in its current state
    processlist_info - statement the thread is executing
    parent_thread_id - if the thread is a subthread, the thread_id of the spawning thread
    connection_type - protocol used ( TCP/IP - TCP/IP without encryption, SSL/TLS - TCP/IP with encryption, Socket - Unix socket file, Named Pipe - Windows named pipe, Shared Memory - Windows shared memory)
    thread_os_id - the thread or task identifier as defined by the OS
    	select count(*) from performance_schema.threads;  - current threads
    	select name, count(*) from performance_schema.threads group by name;	- threads by name
    	select processlist_user, count(*) from performance_schema.threads group by processlist_user;	- threads by user
    	select processlist_host, count(*) from performance_schema.threads group by processlist_host;	- threads by host
    	select processlist_command, count(*) from performance_schema.threads group by processlist_command;	- threads by command 
    
    	select * from performance_schema.threads where processlist_command <> 'Sleep' and processlist_time > 1;	- long running queries	
    	select concat('kill query ', processlist_id,';') from performance_schema.threads 
    				where processlist_command = 'Query' and processlist_time > 600 and processlist_user = 'reports';
    
    	SELECT t1.object_name, t2.table_rows FROM performance_schema.table_io_waits_summary_by_table t1, information_schema.tables t2
    	WHERE t1.object_schema = t2.table_schema and t1.object_name = t2.table_name and t1.object_type = 'TABLE'
    	and t1.count_star = 0 AND object_schema = 'db1';		- unused tables
    Checking ALTER TABLE statement progress
    	UPDATE performance_schema.setup_instruments SET ENABLED='YES' WHERE NAME='stage/sql/copy to tmp table';
    	UPDATE performance_schema.setup_consumers SET ENABLED='YES' WHERE NAME LIKE 'events_stages_%';
    	
    	SELECT * from performance_schema.events_stages_current;
    Sys schema

    The sys schema includes a set of objects that helps interpret data collected by the performance schema. sys schema objects can be used for typical tuning and diagnosis use cases. The objects include views, procedures and functions that summarize performance schema data, perform performance schema configuration and generate diagnostic reports. Many of the views have a version with a x$ prefix that provide raw data suitable for use with other tools.

    The host_summary_by_file_io view summarizes file I/O and latencies grouped by host.
    	SELECT * FROM sys.host_summary_by_file_io;
    	SELECT * FROM sys.x$host_summary_by_file_io;
    The innodb_lock_waits view summarizes the locks that transactions are waiting for, sorted by descending lock age.
    	select * from sys.innodb_lock_waits;
    The version view provides the sys schema and mysql versions.
    	SELECT * FROM sys.version;
    InnoDB monitors

    InnoDB monitors provide information about the InnoDB internal state, useful for performance tuning. When turned on, InnoDB monitors print data about every 15 seconds to the error log.
    	SET GLOBAL innodb_status_output=ON;		- enable standard monitor	
    	SET GLOBAL innodb_status_output_locks=ON;	- enable locks monitor
    		
    	SHOW ENGINE INNODB STATUS\G	- obtain standard monitor output on demand
    The standard InnoDB Monitor displays the following info:

    Background thread Work done by the main background thread Semaphores
    Reservation count - indicates how often InnoDB has allocated slots for semaphores in the OS wait array
    Signal count - measures how often threads have been signaled via the array
    InnoDB first tries to spin-wait for the lock and if it doesn't succeed after the number of spin rounds specified by innodb_sync_spin_loops, falls back to the more expensive OS wait array.

    Reports threads waiting for a semaphore and how many times threads have needed a spin or a OS wait on a mutex or a rw-lock semaphore. A large number of threads waiting for semaphores may be a result of disk I/O or contention due to heavy parallelism of queries or problems in OS thread scheduling. Setting innodb_thread_concurrency to smaller than the default value may help. The Spin rounds per wait line shows the number of spinlock rounds per OS wait for a mutex.
    Latest foreign key error
    Latest detected deadlock
    Transactions Lock waits for transactions
    Table and record locks held by active transactions
    File I/O Information about threads that InnoDB uses to perform various types of I/O. The first few are dedicated to general InnoDB processing. The contents also display information for pending I/O operations and statistics for I/O performance. The number of these threads are controlled by the innodb_read_io_threads and innodb_write_io_threads parameters. Insert buffer and adaptive hash index Shows change buffer and adaptive hash index statistics
    size - The number of pages used within the change buffer. Change buffer size is equal to seg size - (1 + free list len). The 1 + value represents the change buffer header page
    seg size - The size of the change buffer, in pages
    Log Displays current LSN, how far the log has been flushed to disk and the last checkpoint LSN Buffer pool and memory - metrics pertaining to the operation of the InnoDB buffer pool
    Dictionary memory allocated - total memory allocated to the InnoDB data dictionary (bytes). Innodb allocates approximately 15 KB per table 
    	once a table is accessed and keeps it until the server is shut down
    Buffer pool size - total pages allocated to the buffer pool
    Free buffers - pages in the buffer pool free list
    Database pages - pages in the buffer pool LRU list
    Old database pages - pages in the old LRU sublist
    Modified db pages - modified pages
    Pending reads - number of pages waiting to be read into the buffer pool
    Pending writes LRU - number of old dirty pages within the buffer pool to be written from the bottom of the LRU list
    Pending writes flush list - number of pages to be flushed during checkpointing
    reads/s,creates/s,writes/s - average number of buffer pool pages read/created/written per second
    LRU len - pages in the buffer pool LRU list
    unzip_LRU len - pages in the unzip_LRU list. Uncompressed tables only use the LRU. If a table is compressed then compressed pages are on 
    	the LRU and the unzip_LRU is used for pages that have an uncompressed and compressed version in the buffer pool
    Row operations The queries inside InnoDB and queries in queue counters are 0, if there is no limit on concurrent threads (innodb_thread_concurrency = 0). If the SHOW ENGINE INNODB STATUS output is empty, the /tmp directory may have been filled up or be inaccessible, since to print the SHOW INNODB STATUS, InnoDB writes to a tmpfile that it has opened at the mysqld startup.

    The InnoDB Lock Monitor prints additional lock information along with the standard output.

    Monitoring memory usage

    Most Performance Schema memory instrumentation is disabled by default and instruments can be enabled by updating the ENABLED column of the performance_schema.setup_instruments table. Memory instruments have names in the form of memory/code_area/instrument_name, where code_area is a value such as sql or innodb and instrument_name is the instrument detail.
    	SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%memory%';	- all memory instruments
    	SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%memory/innodb%';	- innodb memory instruments
    	
    	update performance_schema.setup_instruments set enabled='YES' where name like 'memory%';
    The below rule can be added to the config file to enable memory instruments.
    	performance-schema-instrument='memory/%=COUNTED'
    Querying memory usage instruments
    	SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/innodb%';
    	SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name LIKE 'memory/sql%';
    Aggregating currently allocated memory (current_alloc) by code area
    	SELECT SUBSTRING_INDEX(event_name,'/',2) AS code_area, sys.format_bytes(SUM(current_alloc)) AS current_alloc
    	FROM sys.x$memory_global_by_current_bytes GROUP BY SUBSTRING_INDEX(event_name,'/',2) ORDER BY SUM(current_alloc) DESC;

    Back



    TRANSACTION/QUERY MANAGEMENT

    Transaction handling

    MySQL operates in AUTOCOMMIT mode by default. i.e unless a transaction is explicitly begun, it automatically executes each query in a separate transaction. SET autocommit disables or enables the default autocommit mode for the current session. If set to 0, COMMIT/ROLLBACK must be issued explicitly.
    	SET GLOBAL autocommit = 1;   (or 0/ON/OFF)
    START TRANSACTION or BEGIN starts a new transaction. COMMIT/ROLLBACK commit or cancel the current transaction's changes. Some statements cannot be rolled back like data definition language (DDL) statements, such as those that create or drop databases, create, drop or alter tables or stored routines. Most of these statements also perform an implicit commit and should not be included within transactions.

    With START TRANSACTION, autocommit remains disabled until the transaction is ended with COMMIT or ROLLBACK.

    The innodb_flush_log_at_trx_commit variable controls the balance between strict ACID compliance for commits and higher performance that is possible when commits are rearranged and done in batches. Better performance can be achieved by changing the default value, but up to a second of transactions can be lost in a crash.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_flush_log_at_trx_commit';
    1 - default and is required for full ACID compliance. The contents of the InnoDB log buffer are written out to the log file at each transaction commit and the log file is flushed to disk
    0 - the contents of the log buffer are written to the log file approximately once per second and the log file is flushed to disk. No writes from the log buffer to the log file are performed at transaction commit. Once-per-second flushing is not guaranteed 100% every second due to process scheduling issues. With any mysqld process crash up to a second of transactions can be lost
    2 - the contents of the log buffer are written to the log file after each commit and the log file is flushed to disk approximately once per second. Once-per-second flushing is not 100% guaranteed every second and since the flushing to disk is done once per second, with any crash up to a second of transactions can be lost
    The SAVEPOINT statement sets a named transaction savepoint with a name of identifier. If the current transaction has a savepoint with the same name, the old savepoint is deleted and a new one is set. The ROLLBACK TO SAVEPOINT statement rolls back a transaction to the named savepoint without terminating the transaction. The RELEASE SAVEPOINT statement removes the named savepoint from the set of savepoints of the current transaction. No commit or rollback occurs.
    	SAVEPOINT identifier
    	ROLLBACK [WORK] TO [SAVEPOINT] identifier
    	RELEASE SAVEPOINT identifier
    Isolation levels

    SET TRANSACTION ISOLATION LEVEL level is used to set the isolation level of the transaction. level can be REPEATABLE READ, READ COMMITTED, READ UNCOMMITTED or SERIALIZABLE. The default isolation level for InnoDB is REPEATABLE READ.
    	SHOW GLOBAL VARIABLES LIKE 'tx_isolation';		- transaction isolation-level. Defaults to REPEATABLE-READ.
    	SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;	- change isolation level
    	SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; insert into t1 SELECT * FROM t2 ; COMMIT ;	- select with no lock

    InnoDB locks

    InnoDB implements standard row-level locking with two types of locks - shared and exclusive. A shared (S) lock permits the transaction that holds the lock to read a row. An exclusive (X) lock permits the transaction to update or delete a row.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';	- seconds that a transaction waits for a row lock before giving up
    Intention locks

    InnoDB supports multiple granularity locking which permits coexistence of row-level locks and locks on entire tables using intention locks. Intention locks are table-level locks in InnoDB that indicate which type of lock (shared or exclusive) a transaction will require later for a row in that table.

    There are two types of intention locks - Intention shared (IS) and Intention exclusive (IX). Before a transaction can acquire a shared lock on a row in a table, it must first acquire an IS lock or stronger on the table and before acquiring an exclusive lock on a row in a table, it must first acquire an IX lock on the table.

    Intention locks do not block anything except full table requests (for e.g LOCK TABLES ... WRITE). The main purpose of intention locks is to show that someone is locking a row or going to lock a row in the table. Table-level lock type compatibility is shown in the below matrix.
    			X	IX	S	IS
    			-	--	-	--
    		X	x	x	x	x
    		IX	x	ok	x	ok
    		S	x	x	ok	ok
    		IS	x	ok	ok	ok
    Transaction data for an intention lock appears similar to the following in SHOW ENGINE INNODB STATUS and InnoDB monitor output.
    	TABLE LOCK table `test`.`t` trx id 10080 lock mode IX
    Record locks

    A record lock is a lock on an index record and prevents any other transaction from inserting, updating or deleting matching rows. For e.g, SELECT col1 FROM t1 WHERE col1 = 10 FOR UPDATE prevents inserting, updating or deleting rows where the value of col1 = 10.

    Record locks always lock index records and if a table is defined with no indexes, InnoDB creates a hidden clustered index and uses this index for record locking.

    Transaction data for a record lock appears similar to the following in the InnoDB monitor output
    	RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t1` trx id 10078 lock_mode X locks rec but not gap
    	Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
    	0: len 4; hex 8000000a; asc     ;;
    	1: len 6; hex 00000000274f; asc     'O;;
    Gap locks

    A gap lock is a lock on a gap between index records or a lock on the gap before the first or after the last index record and prevents other transactions from inserting a value within a range because the gaps between all existing values in the range are locked. For e.g, SELECT col1 FROM t1 WHERE col1 BETWEEN 10 and 20 FOR UPDATE prevents inserting a value of 15 into column col1.

    A gap might span a single index value, multiple values or even be empty. Gap locks are part of the trade-off between performance and concurrency and are used in some transaction isolation levels and not others. Gap locking is not needed for statements that lock rows using a unique index to search for a unique row.

    Gap locks in InnoDB are purely inhibitive, they only stop other transactions from inserting to the gap and do not prevent them from taking gap locks on the same gap. Thus, a gap X-lock has the same effect as a gap S-lock.

    Next-Key Locks

    A next-key lock is a combination of a record lock on the index record and a gap lock on the gap before the index record. If one session has a shared or exclusive lock on record R in an index, another session cannot insert a new index record in the gap immediately before R in the index order.

    By default, InnoDB operates in REPEATABLE READ transaction isolation level and uses next-key locks for searches and index scans, which prevents phantom rows.

    Transaction data for a next-key lock appears similar to the following in SHOW ENGINE INNODB STATUS and InnoDB monitor output.
    	RECORD LOCKS space id 58 page no 3 n bits 72 index `PRIMARY` of table `test`.`t` trx id 10080 lock_mode X
    	Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
    	0: len 8; hex 73757072656d756d; asc supremum;;
    
    	Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
    	0: len 4; hex 8000000a; asc     ;;
    	1: len 6; hex 00000000274f; asc     'O;;
    	2: len 7; hex b60000019d0110; asc        ;;
    Insert Intention Locks

    An insert intention lock is a type of gap lock set by INSERT operations prior to row insertion. This lock signals the intent to insert in such a way that multiple transactions inserting into the same index gap need not wait for each other if they are not inserting at the same position within the gap. Suppose that there are index records with values of 4 and 7. Separate transactions that attempt to insert values of 5 and 6, each lock the gap with insert intention locks prior to obtaining the exclusive lock on the inserted row, but do not block each other as the rows are non-conflicting.

    Transaction data for an insert intention lock appears similar to the following in SHOW ENGINE INNODB STATUS and InnoDB monitor output.
    	RECORD LOCKS space id 31 page no 3 n bits 72 index `PRIMARY` of table `test`.`child` trx id 8731 lock_mode X locks gap before rec insert intention waiting
    	Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
    	0: len 4; hex 80000066; asc    f;;
    	1: len 6; hex 000000002215; asc     " ;;
    	2: len 7; hex 9000000172011c; asc     r  ;;...
    Locking reads

    Regular SELECT statements do not take any locks under any isolation level. If data is queried and then related data is updated/inserted within the same transaction, the regular SELECT statement does not give enough protection as other transactions can update or delete the same rows queried. InnoDB supports two types of locking reads that offer extra safety.

    SELECT...LOCK IN SHARE MODE sets a shared mode lock (IS) on any rows that are read. Other sessions can read the rows, but cannot modify them until the transaction commits.

    SELECT...FOR UPDATE locks the rows (IX) and any associated index entries, the same as issuing an UPDATE statement for those rows. Other transactions are blocked from updating those rows, from doing SELECT ... LOCK IN SHARE MODE, or from reading the data in certain transaction isolation levels till a COMMIT is issued. Locking of rows for update using SELECT FOR UPDATE only applies when autocommit is disabled (either by beginning transaction with START TRANSACTION or by setting autocommit to 0. If autocommit is enabled, the rows matching the specification are not locked.

    Deadlocks

    When innodb_deadlock_detect is enabled (the default), the lock wait timeout value does not apply to deadlocks and InnoDB detects deadlocks immediately and rolls back one of the transactions. When innodb_deadlock_detect is disabled, InnoDB relies on innodb_lock_wait_timeout for rollback when a deadlock occurs.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_deadlock_detect';
    If frequent deadlock warnings cause concern, debugging information can be collected in the error log by enabling the innodb_print_all_deadlocks variable and turning it off later.
    	SHOW GLOBAL VARIABLES LIKE 'innodb_print_all_deadlocks';
    On high concurrency systems, deadlock detection can cause a slowdown when numerous threads wait for the same lock and it may be efficient to disable deadlock detection and rely on innodb_lock_wait_timeout for transaction rollback when a deadlock occurs.

    Table locks

    MySQL enables client sessions to acquire table locks explicitly for cooperating with other sessions for access to tables, or to prevent other sessions from modifying tables during periods when a session requires exclusive access to them.

    LOCK TABLES and SELECT privilege is needed for each object to be locked.
    	LOCK TABLE tb1 READ;	- lock a table in read mode for the current session
    	LOCK TABLE tb1 WRITE;
    	UNLOCK TABLES;		- releases any table locks held by the current session
    The session that holds the READ lock can read the table (but not write it). Multiple sessions can acquire a READ lock for the table at the same time. Other sessions can read the table without explicitly acquiring a READ lock.

    The session that holds the WRITE lock can read and write the table. No other session can access the table until the lock is released. Lock requests for the table by other sessions are blocked while the WRITE lock is held.

    Auto-increment locking

    InnoDB provides a configurable locking mechanism that can improve scalability and performance of SQL statements that add rows to tables with AUTO_INCREMENT columns. The lock mode used for generating auto-increment values is set by the innodb_autoinc_lock_mode parameter. Permissible values are 0, 1 or 2 for traditional, consecutive or interleaved respectively.
    	show global variables like 'innodb_autoinc_lock_mode';

    Transaction and locking information

    The innodb_trx table has info about every transaction (excluding read-only transactions) currently executing inside InnoDB.
    	select * from information_schema.innodb_trx;
    The table has these columns
    	trx_id - unique ID number, not created for for read-only, non-locking transactions
    	trx_lock_structs - number of locks reserved
    	trx_mysql_thread_id - thread_id (the id column of processlist table)
    	trx_operation_state - the transaction's current operation (inserting, fetching rows, flushing log, starting index read, updating or deleting)
    	trx_started - start time
    	trx_state - running, lock wait, rolling back, committing
    	trx_tables_locked - number of tables the statement has row locks on
    	trx_rows_locked - the approximate number or rows locked by this transaction
    	trx_rows_modified - the number of modified and inserted rows in this transaction
    The INNODB_LOCKS table contains information about each lock that an InnoDB transaction has requested but not yet acquired, and each lock that a transaction holds that is blocking another transaction. (LOCK_TRX_ID - id of the transaction holding the lock)

    The INNODB_LOCK_WAITS table contains one or more rows for each blocked InnoDB transaction, indicating the lock it has requested and any locks that are blocking that request. Details about the lock can be found by joining with INNODB_LOCKS on LOCK_ID.
    	SHOW OPEN TABLES WHERE database = 'db1' and in_use > 0;	- show locked tables, in_use = number of locks & lock requests
    	
    	SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;		- requested and blocking locks
    	SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;	- blocked transactions and blocking locks
    	 
    	SELECT  r.trx_id waiting_trx, r.trx_query waiting_query,  b.trx_id blocking_trx_id, b.trx_query blocking_query
    		FROM information_schema.innodb_lock_waits w, information_schema.innodb_trx b, information_schema.innodb_trx r
    		WHERE b.trx_id = w.blocking_trx_id and r.trx_id = w.requesting_trx_id;
    Semaphores and mutexes

    A semaphore is a lock structure consisting of a state and a counter for acquired locks used internally by mysqld and the OS to control access to database resources that may be shared among running threads.

    A mutex (mutually exclusive) is a specialized binary semaphore and is used in the code to enforce that only one thread at a given time can have access to a common resource. When threads executing in the server need to access the same resource, the first thread to obtain a lock on the mutex causes the other threads to wait until the lock is released.
    	show engine innodb mutex;	- displays InnoDB mutex and rw-lock statistics 
    	
    	SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%wait/synch/mutex/innodb%';	- available InnoDB mutex wait instruments
    Mutexes:
    buf_pool - all the control data structures of the buffer pool
    flush_list - the buffer pool flush list
    lock_sys_page - page lock queue shards
    log_sys - log data structures and LSN
    log_buf - writes to buffer pool pages due to mini-transactions


    Query optimization

    Buffering

    join_buffer_size

    The minimum size of the buffer that is used for plain index scans, range index scans and joins doing full table scans. Unless Batched Key Access (BKA) is used (in the optimizer_switch variable), there is no gain from setting the buffer larger than required to hold each matching row, and all joins allocate at least the minimum size, so the global setting should be small and changed to a larger setting only in sessions that are doing large joins. Memory allocation time can cause performance drops if the global size is larger than needed by most queries that use it.

    When BKA is used, join_buffer_size defines how large the batch of keys is in each request to the storage engine. The larger the buffer, the more sequential access will be to the right hand table of a join operation, which can improve performance.
    		SHOW GLOBAL VARIABLES LIKE 'join_buffer_size';	- default 256kB
    sort_buffer_size

    Each session that performs a sort allocates a buffer of this size. If the sort_merge_passes status variable is large, sort_buffer_size can be increased to speed up ORDER BY or GROUP BY operations that cannot be improved with query optimization or indexing. It is better to increase it as a session setting as increasing it globally will slow down most queries that sort for memory allocation.
    	SHOW GLOBAL VARIABLES LIKE 'sort_buffer_size';	- default 256kB
    	SHOW GLOBAL STATUS like 'sort_merge_passes';	- number of merge passes the sort algorithm has had to do
    Using Explain

    Explain provides information about how MySQL executes a statement.

    Join types:
    const - const is used when all parts of a PRIMARY KEY or UNIQUE index are compared to constant values. The table has at most one matching row, which is read at the start of the query. Because there is only one row, values from the column in this row can be regarded as constants by the rest of the optimizer. const tables are very fast because they are read only once

    system - The table has only one row (= system table). This is a special case of the const join type

    eq_ref - One row is read from this table for each combination of rows from the previous tables. Other than the system and const types, this is the best possible join type. It is used when all parts of an index are used by the join and the index is a PRIMARY KEY or UNIQUE NOT NULL index

    ref - All rows with matching index values are read from this table for each combination of rows from the previous tables. ref is used if the join uses only a leftmost prefix of the key or if the key is not a PRIMARY KEY or UNIQUE index (in other words, if the join cannot select a single row based on the key value). If the key that is used matches only a few rows, this is a good join type

    range - Only rows in a given range are retrieved, using an index to select the rows. The key column indicates which index is used. The key_len contains the longest key part that was used. The ref column is NULL for this type. range can be used when a key column is compared to a constant using any of the =, <>, >, >=, <, <=, IS NULL, <=>, BETWEEN, or IN() operators

    index - The index join type is the same as ALL, except that the index tree is scanned. MySQL can use this join type when the query uses only columns that are part of a single index. This occurs two ways: a. If the index is a covering index for the queries and can be used to satisify all data required from the table, only the index tree is scanned. In this case, the Extra column says Using index. An index-only scan usually is faster than ALL because the size of the index usually is smaller than the table data
    b. A full table scan is performed using reads from the index to look up data rows in index order. Uses index does not appear in the Extra column
    index_merge - retrieves rows with multiple range scans and merges their results into one. This access method merges index scans from a single table only and can produce unions, intersections or unions-of-intersections of its underlying scans

    ALL - A full table scan is done for each combination of rows from the previous tables. This is normally bad if the table is the first table not marked const and worse in all other cases.

    Extra column info:
    Range checked for each record (index map: N) - MySQL found no good index to use, but some indexes might be used after column values from preceding tables are known. For each row combination in the preceding tables, MySQL checks whether a range or index_merge access method can be used to retrieve rows. Indexes are numbered beginning with 1, in the same order as shown by SHOW INDEX for the table. The index map value N is a bitmask value that indicates which indexes are candidates. For e.g a value of 0x19 (binary 11001) means that indexes 1, 4 and 5 will be considered.
    Select tables optimized away - The optimizer determined that at most one row should be returned and the rows to be read can be read during the optimization phase (by reading index rows) and no reads are needed during query execution
    Using filesort - MySQL must do an extra pass to retrieve the rows in sorted order by going through all rows that match the WHERE clause according to the join type and storing the sort key and pointer. The keys then are sorted and the rows retrieved in sorted order
    Using index - The column information is retrieved from the table using only the index tree without having to read the actual row. This strategy is used when the query uses only columns that are part of a single index
    Using index condition - Tables are read by accessing index tuples and testing them first to determine whether to read full table rows. In this way, index information is used to defer ('push down') reading full table rows unless it is necessary
    Using intersect(...) - algorithm of index_merge
    Using sort_union(...) - algorithm of index_merge
    Using temporary - To resolve the query, MySQL needs to create a temporary table to hold the result. This typically happens if the query contains GROUP BY and ORDER BY clauses
    Using union(...) - algorithm of index_merge
    Using where - A WHERE clause is used to restrict which rows to match against the next table or send to the client

    Query profiling

    The performance schema statement events and stage events can be used to display profiling information that indicates resource usage for statements executed during the course of the current session.

    1. Update the default row in the setup_actors table to disable historical event collection and monitoring for all foreground threads and insert a new row that enables for just the user that will run the query
    	UPDATE performance_schema.setup_actors SET ENABLED = 'NO', HISTORY = 'NO'  WHERE HOST = '%' AND USER = '%';
    	INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE,ENABLED,HISTORY)
    				VALUES('localhost','test_user','%','YES','YES');
    2. Ensure that statement and stage instrumentation is enabled by updating the setup_instruments table
    	UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%statement/%';
    	UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE '%stage/%';
    3. Ensure that events_statements_* and events_stages_* consumers are enabled
    	UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%events_statements_%';
    	UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%events_stages_%';
    4. Run the statement to be profiled under the user account being monitored
    5. Identify the EVENT_ID of the statement by querying the events_statements_history_long table
    	SELECT EVENT_ID, TRUNCATE(TIMER_WAIT/1000000000000,6) as Duration, SQL_TEXT
    	FROM performance_schema.events_statements_history_long WHERE SQL_TEXT like '%10001%';
    6. Query the events_stages_history_long table to retrieve the statement's stage events. Stages are linked to statements using event nesting. Each stage event record has a NESTING_EVENT_ID column that contains the EVENT_ID of the parent statement.
    	SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration
    		FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=31;
    
    		+--------------------------------+----------+
    		| Stage                          | Duration |
    		+--------------------------------+----------+
    		| stage/sql/starting             | 0.000080 |
    		| stage/sql/checking permissions | 0.000005 |
    		| stage/sql/Opening tables       | 0.027759 |
    		| stage/sql/init                 | 0.000052 |
    		| stage/sql/System lock          | 0.000009 |
    		| stage/sql/optimizing           | 0.000006 |
    		| stage/sql/statistics           | 0.000082 |
    		| stage/sql/preparing            | 0.000008 |
    		| stage/sql/executing            | 0.000000 |
    		| stage/sql/Sending data         | 0.000017 |
    		| stage/sql/end                  | 0.000001 |
    		| stage/sql/query end            | 0.000004 |
    		| stage/sql/closing tables       | 0.000006 |
    		| stage/sql/freeing items        | 0.000272 |
    		| stage/sql/cleaning up          | 0.000001 |
    		+--------------------------------+----------+

    Back



    IMPORTING/EXPORTING DATA

    Loading text files

    Load Data statement

    The LOAD DATA INFILE statement reads rows from a text file into a table at a very high speed. It is usually 20 times faster than using INSERT statements.
    	LOAD DATA LOCAL INFILE '\\\\servername\\dir\\subdir\\data.txt' [IGNORE/REPLACE] INTO TABLE t1
    	FIELDS TERMINATED BY '|' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n'	- field and line delimiters and text qualifier
    	IGNORE 1 LINES					- ignore first line
    	(col1, col2, col3);				- columns to load
    	
    	LOAD DATA LOCAL INFILE 'C:\\Users\\vincent\\Documents\\data.txt' INTO TABLE t1	- load a UTF-8 file
    	CHARACTER SET UTF8
    	FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\r\n'
    	IGNORE 1 LINES;
    If LOCAL is specified with LOAD DATA, the file is read by the client program on the client host and sent to the server and if not, the file must be located on the server host and is read directly by the server (needs FILE privilege). When using LOCAL, a copy of the file is created in the server OS's temporary directory, and is not configurable in MySQL. (/tmp on Linux systems and C:\WINDOWS\TEMP on Windows). Lack of sufficient space can cause the load to fail. Both the server (local-infile=1) and client (mysql --local-infile -uroot -p) need to be configured to permit the load.

    Using LOCAL is a bit slower than letting the server access the files directly as the file contents must be sent over the connection by the client to the server. On the other hand, the FILE privilege is not needed to load local files.

    If LOCAL is not specified, the server reads a text file located on the server host and the FILE privilege is required. Non-LOCAL load and export operations are also subject to the secure_file_priv setting. If this variable is a nonempty directory name, the file to be loaded/exported must be located in that directory.
    	show global variables like 'secure_file_priv';
    Field and line handling

    The FIELDS and LINES clauses are optional but FIELDS must precede LINES if both are specified. If FIELDS is specified, at least one of its subclauses (TERMINATED BY, [OPTIONALLY] ENCLOSED BY, ESCAPED BY) must be specified. Arguments to these clauses can only contain ASCII characters.

    IF FIELDS and LINES clauses are not specified, the defaults are FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY ''. \ is the MySQL escape character within strings in SQL statements and to specify a literal backslash, two backslashes must be specified to be interpreted as a single backslash. The escape sequences '\t' and '\n' specify tab and newline characters.

    If IGNORE or REPLACE are not specified without LOCAL, an error occurs when a duplicate key value is found and the rest of the file is ignored. With LOCAL, the default behavior is the same as if IGNORE is specified as the server has no way to stop transmission of the file in the middle.
    	- using SET to insert derived values
    	LOAD DATA INFILE 'file.txt' INTO TABLE t1 (col1, @var1) SET col2 = @var1/100;
    	
    	- using SET to supply values not in file
    	LOAD DATA INFILE 'file.txt' INTO TABLE t1 (col1, col2) SET col3 = CURRENT_TIMESTAMP;
    	
    	- discard an input field by assigning it to an unused user variable
    	LOAD DATA INFILE 'file.txt' INTO TABLE t1 (col1, @dummy, col2);

    Loading xml files

    The LOAD XML INFILE statement reads data from an XML file into a table. By default, the <row> element is considered to be the equivalent of a table row; this can be changed using the ROWS IDENTIFIED BY clause.

    The field names in the XML file should match the column names else those columns are set to null.
    	LOAD XML LOCAL INFILE 'person.xml' INTO TABLE person
    	ROWS IDENTIFIED BY '<person>'
    	SET colx = NOW(), coly = 'processing';
    Exporting table data

    The SELECT INTO OUTFILE statement is the complement of LOAD DATA and exports table data to text files on the server machine (needs FILE privilege). The file should not exist already (cannot be overwritten to safeguard system files) and mysql user may need write permissions on the folder.

    If INTO DUMPFILE is used instead of INTO OUTFILE, MySQL writes only one row into the file, without any column or line termination and without performing any escape processing. This is useful for selecting a BLOB value and storing it in a file.
    	- produce a CSV output file
    	SELECT * INTO OUTFILE '/tmp/table1.txt'	FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM table1;
    FIELDS ESCAPED BY controls how to write special characters and is used when necessary to avoid ambiguity as a prefix that precedes following characters on output
  • the FIELDS ESCAPED BY character
  • the FIELDS [OPTIONALLY] ENCLOSED BY character
  • the first character of the FIELDS TERMINATED BY and LINES TERMINATED BY values
  • ASCII NUL

    The FIELDS TERMINATED BY, ENCLOSED BY, ESCAPED BY and LINES TERMINATED BY characters must be escaped so that the file can be read back in reliably.
    	SELECT * INTO OUTFILE '/tmp/t1.txt'
    	FIELDS TERMINATED BY '\t' OPTIONALLY ENCLOSED BY '"', ESCAPED BY '\'
    	LINES TERMINATED BY '\n'
    	FROM t1;
    The below example executes a query in a loop and writes out multiple files.
    	DELIMITER $$
    	DROP PROCEDURE IF EXISTS  `usp_create_txn_files`$$
    	CREATE PROCEDURE `usp_create_txn_files`()
    	BEGIN
            DECLARE DECLARE did INT; DECLARE dcode VARCHAR(255); DECLARE bmonth TINYINT UNSIGNED; DECLARE filename VARCHAR(255);
    		DECLARE stdate DATETIME; DECLARE enddate DATETIME;
    		SET did = 0;
    		DROP  TEMPORARY TABLE IF EXISTS result;
    		CREATE TEMPORARY TABLE result (d_code VARCHAR(255), txn_id VARCHAR(255), txn_date VARCHAR(20), quantity VARCHAR(255));
    
    		SELECT MIN(id) INTO did FROM t1 WHERE STATUS = 1 AND id > did;
    		WHILE (did IS NOT NULL) DO
    			SELECT code INTO dcode FROM t1 WHERE id = did;
    			SET bmonth = 3;
    			WHILE (bmonth < 6) DO
    				SET stdate = CONCAT('2018-',LPAD(bmonth,2,'00'),'-01 00:00:00');
    				SET enddate = CONCAT(LAST_DAY(stdate), ' 23:59:59');
    				TRUNCATE TABLE result;
    				INSERT INTO result VALUES ('d_code','txn_id','txn_date','quantity');
    				INSERT INTO result SELECT * FROM bill b WHERE d_code = dcode AND txn_date BETWEEN stdate AND enddate;
    				SET filename =  CONCAT('/txn_files/txns_',dcode,'_2018', LPAD(MONTH(stdate),2,'00'),'.txt');
    				SET @sqlout = CONCAT("select * into outfile '", filename, "' FIELDS TERMINATED BY '|' ESCAPED BY '' LINES TERMINATED 
    				BY '\\n'", " from result;");
    				PREPARE stmt FROM @sqlout;
    				EXECUTE stmt;
    				DEALLOCATE PREPARE stmt;
    				SET bmonth = bmonth + 1;
    			END WHILE;
    			SELECT MIN(id) INTO did FROM t1 WHERE STATUS = 1 AND id > did;
    		END WHILE;
    		DROP TEMPORARY TABLE result;
    	END$$
    	DELIMITER ;

    Back


    BACKUP/RECOVERY

    Backups and Restores

    The MySQL Enterprise Backup product does a hot backup of all InnoDB tables. MyISAM and other non-InnoDB tables are backed up last, using the warm backup technique: the database continues to run, but the system is in a read-only state during that phase of the backup.

    MySQL Enterprise Backup performs physical backups. Logical backup tools include the mysqldump program and the SELECT ... INTO OUTFILE statement. These work for any storage engine, even MEMORY.

    Full and Point-in-Time (incremental) recovery

    A full recovery restores all data from a full backup. Point-in-time recovery is based on the binary log and typically follows a full recovery from the backup files that restores the server to its state when the backup was made. Then the data changes written in the binary log files are applied as incremental recovery to redo data modifications and bring the server up to the desired point in time.


    mysqldump

    The mysqldump client is a backup program that takes logical backups and can be used to dump MySQL databases for backup or transfer to another SQL server. The dump typically contains SQL statements to create/populate tables but can also be used to generate files in CSV, other delimited text or XML format.

    Options
    	--all-databases		dump all tables in all databases
    	--events, -E		include event scheduler events (disabled by default)
    	--flush-logs		flush the log files before starting the dump. Requires the RELOAD privilege. Closes current binary log file and 
    					creates a new one to set up a recovery point
    	--force, -f		ignore all errors during a table dump
    	--insert-ignore		write INSERT IGNORE rather than INSERT statements
    	--no-autocommit		enclose the INSERT statements for each dumped table within SET autocommit = 0 and COMMIT statements
    	--no-create-info, -t	data only, no CREATE TABLE statements
    	--no-data, -d		structure only
    	--quick, -q		useful for dumping large tables, dumps one row at a time instead of retrieving the entire row set and buffering 
    					it in memory
    	--routines, -R		include stored routines in the dump (disabled by default)
    --set-gtid-purged=AUTO/ON/OFF controls the inclusion of a SET @@GLOBAL.gtid_purged statement and a SET @@SESSION.sql_log_bin=0 statement (which disables binary logging and prevents new GTIDs from being generated when reloading) in the output AUTO - the default value. If GTIDs are enabled on the server and gtid_executed is not empty, SET @@GLOBAL.gtid_purged is added to the output, containing the GTID set from gtid_executed. If GTIDs are enabled, SET @@SESSION.sql_log_bin=0 is added to the output OFF - SET @@GLOBAL.gtid_purged and SET @@SESSION.sql_log_bin=0 are not added to the output ON - if GTIDs are enabled, SET @@GLOBAL.gtid_purged (unless gtid_executed is empty) and SET @@SESSION.sql_log_bin=0 are added to the output. An error occurs if this option is set but GTIDs are not enabled
    --single-transaction sets the transaction isolation mode to REPEATABLE READ and sends a START TRANSACTION SQL statement to the server before dumping data. Useful with transactional tables, it dumps the consistent state of the database at the time when START TRANSACTION was issued without blocking any applications --skip-add-drop-table no DROP TABLE statements --skip-add-locks no LOCK TABLES and UNLOCK TABLES statements surrounding each table dump --skip-lock-tables do not lock tables before dumping them --triggers include triggers (enabled by default) --xml, -X write dump output as well-formed XML
    mysqldump requires at least the SELECT privilege for dumped tables, SHOW VIEW for dumped views, TRIGGER for dumped triggers and LOCK TABLES if the --single-transaction option is not used.
    	mysqldump db1 > /home/dir/db1.sql		- dump a database
    	mysqldump --all-databases > all_dbs.sql		- dump all databases
    	mysqldump --databases db1 db2 > some_dbs.sql	- dump specific databases
    	
    	mysqldump db1 t1 t2 t3 > t123.sql		- dump tables t1, t2, t3 only
    	mysqldump db1 --ignore-table=t1 --ignore-table=t2 > db1.sql - dump all tables except t1, t2
    	mysqldump db1 tbl1 >> multitbl.sql		- append to existing dump
    	
    	mysqldump -u user -p pwd --databases db1 --tables t1 --where="id < 1000" > dump.sql	- using where
    	mysqldump -u user -p pwd --databases db1 --tables t1 --where="1 limit 100" > dump.sql	- using limit
    	mysqldump -u user -p pwd --databases db1 --tables t1 --where="id in (select id from t2)" > dump.sql  - using subquery
    	
    	mysql dbname < /dir1/db_full.sql	- restore from dump
    	mysql -hHostname dbname < /dir1/db_full.sql	- restore in a different host
    To dump a database with stored procedures, SELECT privilege is needed on the mysql.proc table.
    	GRANT SELECT ON mysql.proc to 'mysqldump-user';

    Troubleshooting/Recovery

    MySQL startup problems

    If Errcode 13 (Permission denied) is got when starting mysqld, the privileges of the data directory or its contents do not permit server access and the permissions need to be changed for the involved folders and files so that the server has the right to use them. The server can also be started as root, but this raises security issues and should be avoided.
    Can't start server: Bind on TCP/IP port: Address already in use/Bind on unix socket... - TCP/IP port or Unix socket file is being used by another mysqld or program
    mysql.service: Start request repeated too quickly - Invalid entry in the config file
    On Windows, if the MySQL service doesn't startup with the Error 1067: The process terminated unexpectedly, it could be due to mysqld.exe already running (but not as a service) and occupying port 3306. When the service tries to start and sees that port 3306 is already taken, it fails. If mysqld.exe is seen running in the Windows task manager it can be killed and service can be started again.

    Connection errors

    A MySQL client on Unix can connect to the mysqld server in two ways - by using a Unix socket file to connect through a file in the file system (default /tmp/mysql.sock) or by using TCP/IP which connects through a port number. A Unix socket file connection is faster than TCP/IP but can be used only when connecting to a server on the same computer. A Unix socket file is used if a host name is not specified or localhost is specified.
    	show global variables like 'socket';	- the name of the socket file(Unix)/named pipe(Windows) used for local client connections
    On a MySQL server running on Windows, TCP/IP can be used to connect. If the server is started with the --enable-named-pipe option, named pipes can also be used to connect if the client is running on the same host as the server. The name of the named pipe is MySQL by default. If a host name is not specified when connecting to mysqld, a MySQL client first tries to connect to the named pipe. If that does not work, it connects to the TCP/IP port. The use of named pipes on Windows can be forced by using . as the host name.

    The error '2002 Can't connect to local MySQL server through socket' normally means that there is no MySQL server running on the system or that an incorrect Unix socket file name or TCP/IP port number are being used or the TCP/IP port has been blocked by a firewall or port blocking service.

    The error '2003 Can't connect to MySQL server on server (10061)' indicates that the network connection has been refused. The server may not be running, may not have network connections enabled or the port specified is not correct.
    	ps xa | grep mysqld		- check if mysqld process is running
    The error '2013 Lost connection to MySQL server during query' has these likely causes
  • network connectivity trouble - the condition of the network needs to be checked
  • too many rows are being sent as part of one or more queries - net_read_timeout can be increased from its default of 30 seconds to 60 seconds or longer, sufficient for the data transfer to complete
  • BLOB values that are larger than max_allowed_packet, which may need to be increased

    Rarely, the 'Lost connection to MySQL' error can happen when the client is attempting the initial connection to the server. In this case, the problem may be resolved by increasing the connect_timeout value, particularly for a very long distance or slow connection. The cause can be confirmed by
    	SHOW GLOBAL STATUS LIKE 'Aborted_connects';
    which increases by one for each initial connection attempt that the server aborts. If 'reading authorization packet' is seen as part of the error message, this is the solution needed.

    If a client successfully connects but later disconnects improperly or is terminated, the server increments the Aborted_clients status variable and logs an Aborted connection message to the error log. The cause can be any of the following
  • the client program did not call mysql_close() before exiting
  • the client had been sleeping more than wait_timeout or interactive_timeout seconds without issuing any requests to the server
  • the client program ended abruptly in the middle of a data transfer
    	SHOW GLOBAL STATUS LIKE 'Aborted_clients'; -  number of connections aborted because the client died without closing the connection properly
    Forcing innodb recovery

    MySQL tablespaces or data/index files may get corrupted by mysqld being killed or crashing in the middle of an update, low-quality hardware, external program manipulating data or index files at the same time as mysqld without locking the table properly, tampering of files in the data folder or bugs in the software.

    The usual way to recover a corrupted database is to dump the tables and restore them back. Serious corruption might cause InnoDB background operations or roll-forward recovery to crash and mysqld may not start up. In such cases, the innodb_force_recovery option can be used to force the InnoDB storage engine to start up while preventing background operations from running, so that the tables can be dumped.

    The innodb_force_recovery variable can be set to a value greater than 0 (starting incrementally from 1) so that InnoDB can be started and tables can be dumped. As a safety measure, InnoDB prevents INSERT, UPDATE, or DELETE operations when innodb_force_recovery is greater than 0. Values up to 3 are relatively safer and values above 4 can corrupt the data files. A setting of 4 or above places InnoDB in read-only mode.
    	[mysqld]
    	innodb_force_recovery = 1	- possible values 0 (default) to 6
    Data dictionary errors

    If a file-per-table tablespace file (.ibd file) is missing, the below messages appear at startup. The DROP TABLE statement can be issued to remove data about the missing table from the data dictionary.
    	[ERROR] InnoDB: Cannot open datafile for read-only: './db1/t1.ibd' OS error: 71
    	[Warning] InnoDB: Ignoring tablespace `db1/t1` because it could not be opened
    The below message appears if there is an orphan .frm file without the .ibd file or the tablespace id of the .ibd file doesn't match the one in the data dictionary.
    	[Warning] InnoDB: Cannot open table db1/t1 from the internal data dictionary of InnoDB though the .frm file for the table exists
    Server error codes
    1022 Can't write; duplicate key in table 't1' - foreign key names must be unique in a database
    1030 Got error xx from storage engine - check OS error code xx
    1032 Can't find record in 'table' - missing data in replication slave
    1034 Incorrect key file table 't1', try to repair it - possible tmpdir out of space while altering table
    1040 Too many connections - max_connections limit has been reached, connect as SUPER user to analyze
    1050 Table already exists - when moving table to another DB by renaming, check for duplicate foreign keys
    1062 Duplicate entry 'x' for key 'keyname'
    1114 Table 'x' is full - shortage of disk/mount space, temp folder space or ibdata1 file space
    1129 Host is blocked due to many connection errors - max_connect_errors has been exceeded, use FLUSH HOSTS or mysqladmin flush-hosts
    1130 Host is not allowed to connect to this server - user with hostname (or %) doesn't exist in mysql.user
    1133 Can't find any matching row in the user table - trying to grant to a non-existent user
    1135 Can't create a new thread - reduce max_connections variable and if using 32-bit mysql upgrade to 64-bit for gaining access to more memory
    1142 Command denied to user for table - lack of privilege or incorrect table or database name
    1143 Select command denied for user for column in table - if user is empty, user who created view is not in mysql.user
    1146 Table 'db1.t1' doesn't exist when using LOCK TABLES (mysqldump) - corrupted table, discard tablespace
    1153 Got a packet bigger than 'max_allowed_packet' bytes - client or mysqld server received a packet larger than max_allowed_packet
    1158 Got an error reading communication packets - client connection terminated abnormally or exceeded the max_allowed_packet for queries
    1171 All parts of primary key must be NOT NULL - declare primary key column(s) as not nullable
    1186 Binlog closed, cannot Reset Master - enable binary logging and restart
    1194 Table 't' is marked as crashed and should be repaired - truncate table or restore from backup
    1205 Lock wait timeout exceeded; try restarting transaction
    1206 The number of locks exceeds the lock table size   - buffer pool size is inadequate
    1213 Deadlock found when trying to get lock; try restarting transaction - debug using innodb_print_all_deadlocks
    1215 Cannot add foreign key constraint - possible datatype mismatch (or use SHOW ENGINE INNODB STATUS)
    1231 Variable x can't be set to the value of NULL (mysqldump) - max_allowed_packet can be increased to avoid loss of connection
    1236 Error reading binary log from master; log event exceeded max_allowed_packet -  increase max_allowed_packet of master and use same value for slave
    1236 The master has purged binary logs containing GTIDs that the slave requires - provision a new slave
    1236 Slave has more GTIDs than the master has, using the master's server UUID - GTIDs need to be synchronized
    1265 Data truncated for column - oversized data or formatted number being inserted into a numeric field
    1329 No data - zero rows fetched, selected or processed - handler for no rows found condition is needed for cursor
    1396 Create user failed for 'user'@'%' - user with same name exists already
    1418 This function has none of DETERMINISTIC, NO SQL or READS SQL DATA in its declaration and binary logging is enabled - functions must be declared deterministic for binary logging
    1419 You do not have the SUPER privilege and binary logging is enabled - creating/altering functions or triggers needs SUPER privilege for binary logging
    1593 The slave I/O thread stops because master and slave have equal MySQL server UUIDs - delete slave auto.cnf file and restart
    1594 Relay log read failure - corrupted relay log, use RESET SLAVE to recreate the relay logs
    1595 Slave I/O Relay log write failure could not queue event from master - disk full or corrupted binlog
    1682 Native table db.x has the wrong structure - run mysql_upgrade and restart mysqld
    1690 Value is out of range - cast unsigned columns as signed during subtraction
    1701 Cannot truncate a table referenced in a foreign key constraint
    1743 Slave I/O Replication event checksum verification failed while reading from network - may indicate a corrupted binlog
    1789 Master has purged required GTIDs - replicate the missing transactions from elsewhere or provision a new slave from backup
    1799 Creating index 'PRIMARY' required more than 'innodb_online_alter_log_max_size' bytes of modification log - increase variable value or retry when concurrent DML is less
    1812 Tablespace is missing for table - possible corruption of table or .ibd file
    1813 Tablespace exists - .ibd file needs to be removed
    1840 @@global.gtid_purged can only be set when @@global.gtid_executed is empty - use RESET MASTER to clear gtid_executed
    1872 Slave failed to initialize relay log info structure from the repository - Reset slave
    1878 Temporary file write failure  - tmpdir folder is filled up
    3009 Column count of table db.x is wrong. Created with mysql ver1 running with ver2 - run mysql_upgrade and restart mysqld
    3019 Undo log error, no space in system tablespace for undo log pages - disk out of space
    3077 To have multiple channels, repository cannot be of type FILE - change master_info_repository and relay_log_info_repository variables
    Client error codes
    2002 Can't connect to local MySQL server through socket '/var/run/mysqld.sock' - mysqld.exe isn't running or socket file is missing
    2003 Can't connect to MySQL server on 'host' - use 'telnet <server> 3306' to verify server is running
    2006 MySQL server has gone away - server timed out/encountered a large query/a running thread was killed and closed the connection (increase max_allowed_packet/wait_timeout)
    2013 Lost connection to server during query - max_allowed_packet may need to be increased along with net_read_timeout and net_write_timeout
    2059 Authentication plugin cannot be loaded - install plugin or alter user to use an available plugin
    2061 Authentication plugin 'caching_sha2_password' requires secure connection - use --get-server-public-key option to request the RSA public key from the server
    
    Global (server or client) errors

    These errors can be produced by the server or by client programs and have error codes in the range from 1 to 999.
    Can't create/write to file '/home/temp/MYzplJok' (errcode 13) - lack of permissions
    Can't create/write to file '/temp/MYzplJok' (errcode 28) - out of space on device
    Error dropping database (Can't rmdir './db1', errno 17) - database directory has non-table files that need to be removed
    'file_name' not found (errno 23)	- not enough file descriptors have been allocated to MySQL
    Can't open file: file_name (errno 24)	- set open_files_limit to increase the number of file descriptors available to mysqld
    Can't create/write to file 'DB/tmpdir/MY0zlbyt' (errno 24 - Too many open files) - increase open_files_limit

    Back



    USER MANAGEMENT/SECURITY

    User accounts

    MySQL stores accounts in the system table mysql.user. An account is defined in terms of a user name and the client host or hosts from which the user can connect to the server.

    To authenticate client connections for accounts that use MySQL native authentication (implemented by the mysql_native_password authentication plugin), the server uses passwords stored in the user table. If the server authenticates a client using some other plugin, the authentication method that the plugin implements may or may not use a password stored in the user table.
    	CREATE USER 'jeff'@'localhost' IDENTIFIED BY 'pwd';	- user jeff can connect only from the local host
    	CREATE USER 'joe'@'%' IDENTIFIED BY 'pwd';  		- can connect from any host
    	
    	SET PASSWORD FOR 'abe'@'host_name' = 'eagle';	- set/change password
    	DROP USER 'jeffrey'@'localhost';		- takes effect when the user's existing session is closed
    The default_password_lifetime system variable is used to establish automatic password-expiration policy globally. The default value is 0 which disables expiration. A positive value N indicates that the password must be changed every N days.
    	show global variables like 'default_password_lifetime';
    Anonymous user

    An account with a blank user name is an anonymous user.
    	CREATE USER ''@'localhost' identified by 'pwd';
    When a local anonymous user exists, any user who connects from the local host with the correct password for the anonymous user will be permitted access, with the privileges associated with the anonymous-user account.

    Setting Account Resource Limits
    	CREATE USER 'francis'@'localhost' IDENTIFIED BY 'frank'    - use ALTER or GRANT for existing users
             WITH MAX_QUERIES_PER_HOUR 20
                  MAX_UPDATES_PER_HOUR 10
                  MAX_CONNECTIONS_PER_HOUR 5
                  MAX_USER_CONNECTIONS 2;
    Authentication plugins

    MySQL provides two authentication plugins that implement SHA-256 hashing for user account passwords
  • sha256_password - implements basic SHA-256 authentication
  • caching_sha2_password - implements SHA-256 authentication, but uses caching on the server side for better performance and has additional features

    Privileges

    MySQL provides privileges that apply in different contexts and at different levels of operation:

    Administrative privileges - enable users to manage operation of the MySQL server. These privileges are global and not database-specific. They can be assigned by ON *.* FILE - allows read/write of files on the server host
    PROCESS - allows viewing of information about threads executing within the server
    RELOAD - allows use of the FLUSH statement
    REPLICATION CLIENT - to be able to execute replication-related statements
    REPLICATION SLAVE - needed by accounts used by slave servers to connect to this master
    SHOW DATABASES - to be able to see all database names
    SUPER - enables use of administrative operations such as CHANGE MASTER TO, KILL, PURGE BINARY LOGS, SET GLOBAL
    USAGE - no privileges, allow connect only
    Database privileges - apply to a database and to all objects within it. These privileges can be granted for specific databases (db.*), or globally to all databases (*.*) CREATE - enable creation of databases and tables
    CREATE TEMPORARY TABLES - enables the creation of temporary tables
    CREATE ROUTINE - create of stored routines
    CREATE VIEW - enables use of the CREATE VIEW statement
    DROP - drop existing databases, tables and views. Also needed for TRUNCATE TABLE
    EVENT - required to create, alter, drop, or see events for the Event Scheduler
    LOCK TABLES - enables use of explicit LOCK TABLES statements to lock tables (with SELECT privilege)
    Privileges for database objects such as tables, indexes, views and stored routines can be granted for specific objects within a database, for all objects of a given type (e.g all tables) within a database or globally for all objects of a given type in all databases. ALTER - enables the use of the ALTER TABLE statement and renaming tables
    ALTER ROUTINE - alter or drop stored routines
    DELETE - delete rows from a table
    EXECUTE - execute stored routines
    INDEX - create or drop indexes on existing tables
    REFERENCES - create foreign key constraints on a table
    SELECT - select rows from tables
    SHOW VIEW - enables use of the SHOW CREATE VIEW statement
    TRIGGER - create, drop, execute or display triggers for a table
    UPDATE - update rows in tables
    	SHOW PRIVILEGES;	- list of privileges the server version supports
    
    	GRANT SELECT, INSERT ON db1.tbl1 TO 'jeff'@'localhost';
    	REVOKE INSERT ON *.* FROM 'jeff'@'localhost';
    	
    	GRANT SELECT ON *.* TO 'user'@'%' WITH GRANT OPTION;	- allow user to grant privileges
    	
    	SHOW GRANTS FOR 'joe'@'home.example.com';	- show privileges for a user
    	SHOW GRANTS;	- for CURRENT_USER();
    The ALL and ALL PRIVILEGES privilege specifiers are used to grant all privileges available at a given privilege level (except GRANT OPTION).
    	GRANT ALL ON db1.* TO 'joe'@'%';
    The _ and % wildcards are permitted when specifying database names in GRANT statements that grant privileges at the database level. Hence if a database name contains a _ character it needs to be specified as \_ in the GRANT statement to prevent the user from being able to access additional databases matching the wildcard pattern.
    	GRANT SELECT ON `db%`.* to user1;	- grant access to all databases starting with 'db'
    Grant tables

    The information about user accounts and the privileges held by them is contained in several grant tables in the mysql database. The server reads the contents of the grant tables into memory when it starts and the tables can be reloaded by issuing a FLUSH PRIVILEGES statement.

    Normally, the contents of these tables are are not modified directly but manipulated indirectly by using statements such as CREATE USER, GRANT and REVOKE to set up accounts and control the privileges available to each account.

    user - contains user accounts, global privileges, and other non-privilege columns
    	SELECT * from mysql.user;
    db - contains database-level privileges
    	SELECT * FROM mysql.db WHERE Db = 'db1';   - show users with access on db
    tables_priv - contains table-level privileges
    columns_priv - contains column-level privileges
    procs_priv - contains stored procedure and function privileges
    proxies_priv - contains proxy-user privileges

    If the server is started with the --skip-grant-tables option, it does not read the grant tables or implement any access control and any user can connect and perform any operation till access checking is enabled by flushing the privileges.

    A grant table reload affects privileges for existing client sessions as follows
  • table and column privilege changes take effect with the client's next request
  • database privilege changes take effect the next time the client executes a USE dbname statement
  • global privileges and passwords are unaffected for a connected client and take effect only in sessions for subsequent connections


    Roles

    Roles are named collections of privileges and they can have privileges granted to and revoked from them like user accounts. A user account can be granted roles which grants to the account the privileges associated with each role. Creating roles requires the CREATE ROLE or CREATE USER privilege.

    Role names, like user account names are in the 'user'@'host' format. The host part defaults to '%', if omitted. The user and host parts can be unquoted unless they contain special characters such as - or %.
    	CREATE ROLE 'app_developer', 'app_read', 'app_write';
    	DROP ROLE 'app_read', 'app_write';
    Dropping a role revokes it from every account to which it was granted. Roles named in the mandatory_roles variable cannot be dropped.
    	GRANT 'app_developer' TO 'user1'@'localhost';
    	REVOKE role1 FROM user1;
    	
    	SHOW GRANTS FOR 'dev1'@'localhost' USING 'app_developer';
    Roles can be specified as mandatory by naming them in the mandatory_roles system variable. The server treats a mandatory role as granted to all users so that it need not be granted explicitly to any account. Setting mandatory_roles at runtime requires the ROLE_ADMIN privilege.
    	SHOW GLOBAL VARIABLES LIKE 'mandatory_roles';
    Roles granted to a user account can be active or inactive within account sessions. If a granted role is not active within a session, its privileges do not apply. The CURRENT_ROLE() function displays active roles within the session.
    	SELECT CURRENT_ROLE();
    To cause all explicitly granted and mandatory roles to be automatically activated when users connect to the server, the activate_all_roles_on_login variable has to be enabled. Automatic role activation is disabled by default.
    	SHOW GLOBAL VARIABLES LIKE 'activate_all_roles_on_login';

    Authenticating connections

    For all connection attempts, the server checks credentials first and then account locking state. If both succeed, the server accepts the connection and then waits for requests.

    Credential checking is performed using the three user table scope columns (Host, User and authentication_string). Locking state is recorded in the user table account_locked column. The server accepts the connection only if the Host and User columns in some user table row match the client host name and user name, the client supplies the password specified in that row and the account_locked value is 'N'.

    For each request that issued through the connection, the server checks whether the use has sufficient privileges using the privilege columns in the grant tables.

    Pluggable authentication

    When a client connects to the MySQL server, the server uses the user name provided by the client and the client host to select the appropriate row from the mysql.user system table, determines the authentication plugin to use and then authenticates the client.

    If the server cannot find the plugin, an error occurs and the connection attempt is rejected. Else the server invokes that plugin to authenticate and return a status indicating whether the user provided the correct password and is permitted to connect.

    Pluggable authentication enables these important capabilities
  • Choice of authentication methods - makes it easy to choose and change the authentication method used for individual MySQL accounts
  • External authentication - makes it possible for clients to connect to the MySQL server with credentials appropriate for authentication methods that store credentials elsewhere than in the mysql.user table. For e.g plugins can be created to use external authentication methods such as PAM, Windows login IDs, LDAP or Kerberos
  • Proxy users - if a user is permitted to connect, an authentication plugin can return to the server a user name different from the name of the connecting user, to indicate that the connecting user is a proxy for another user (the proxied user). While the connection lasts, the proxy user is treated as having the privileges of the proxied user, effectively impersonating one another

    MySQL provides several authentication plugins like native, SHA-256, LDAP, Fido, Kerberos etc. Native authentication is based on the password hashing method in use from before the introduction of pluggable authentication.

    The CREATE USER and ALTER USER statements can specify how an account authenticates.
    	CREATE USER 'user1'@'localhost' IDENTIFIED BY 'password' AND IDENTIFIED WITH authentication_ldap_simple;
    The authentication_policy variable is used to administer multifactor authentication (MFA) capabilities, where factor corresponds to an authentication method or plugin associated with an account.
    	SHOW GLOBAL VARIABLES LIKE 'authentication_policy';	- default *,,
    The value of authentication_policy is a list of 1, 2 or 3 comma-separated elements. Each element can be an authentication plugin name, an asterisk or empty. The first element is mandatory.

  • If element N is an authentication plugin name, an authentication method for factor N is required and must use the named plugin and in addition, the plugin becomes the default plugin for factor N authentication methods that do not name a plugin explicitly.

    Authentication plugins that use internal credentials storage can be specified for the first element only and cannot repeat. For e.g authentication_policy = 'caching_sha2_password, sha256_password' cannot be used

  • If element N is an asterisk (*), an authentication method for factor N is required and it may use any authentication plugin that is valid for element N

  • If element N is empty, an authentication method for factor N is optional. If given, it may use any authentication plugin that is valid for element N

    If element N is missing from the list, an authentication method for factor N is forbidden. For e.g, a value of '*' permits only a single factor and thus enforces single-factor authentication (1FA) for accounts. In this case, CREATE and ALTER USER statements cannot specify authentication for factors 2 or 3.

  • When an authentication_policy element names an authentication plugin, the permitted plugin names for the element are subject to these conditions
  • Element 1 must name a plugin that does not require a registration step. For e.g, authentication_fido cannot be named.
  • Elements 2 and 3 must name a plugin that does not use internal credentials storage.
  • When authentication_policy element N is *, the permitted plugin names for factor N in account definitions are subject to these conditions
  • For factor 1, account definitions can use any plugin. Default authentication plugin rules apply for authentication specifications that do not name a plugin.
  • For factors 2 and 3, account definitions cannot name a plugin that uses internal credentials storage. For example, with '*,*', '*,*,*', '*,', '*,,' authentication_policy settings, plugins that use internal credentials storage are only permitted for the first factor and cannot repeat.
  • When authentication_policy element N is empty, the permitted plugin names for factor N in account definitions are subject to these conditions
  • For factor 1, this does not apply because element 1 cannot be empty.
  • For factors 2 and 3, account definitions cannot name a plugin that uses internal credentials storage.
  • Empty elements must occur at the end of the list, following a nonempty element i.e the first element cannot be empty, and either no element is empty or the last element is empty or the last two elements are empty. For e.g, a value of ',,' is not permitted because it would signify that all factors are optional - accounts must have at least one authentication factor.

    The default value of authentication_policy is '*,,'. This means that factor 1 is required in account definitions and can use any authentication plugin, and that factors 2 and 3 are optional and each can use any authentication plugin that does not use internal credentials storage.

    Encrypted connections

    MySQL supports encrypted connections between clients and the server using the TLS (Transport Layer Security) protocol. MySQL does not use the SSL protocol because it provides weak encryption. TLS incorporates algorithms that provide identity verification using the X509 standard.
    	SHOW VARIABLES LIKE 'have_ssl';			- whether mysqld supports secure connections
    	SHOW GLOBAL VARIABLES LIKE 'tls_version';	- protocols permitted by the server for encrypted connections
    	SHOW SESSION STATUS LIKE 'ssl_version';		- encryption protocol used for an encrypted connection
    Server-side configuration

    The --ssl option specifies that the server permits but does not require encrypted connections and is enabled by default. To make clients connect mandatorily using encrypted connections, the require_secure_transport variable must be enabled.
    	SHOW GLOBAL VARIABLES LIKE 'require_secure_transport';
    These system variables specify the certificate and key files the server uses when permitting clients to establish encrypted connections.
    	[mysqld]
    	ssl-ca=ca.pem			- the Certificate Authority (CA) certificate
    	ssl-cert=server-cert.pem	- the server public key certificate. Can be sent to the client and authenticated against its CA certificate
    	ssl-key=server-key.pem		- the server private key
    Client-side configuration

    By default, MySQL client programs attempt to establish an encrypted connection if the server supports encrypted connections, with further control available through the --ssl-mode option. In the absence of an --ssl-mode option or --ssl-mode=PREFERRED, clients attempt to connect using encryption and if it cannot be established, fall back to an unencrypted connection.
    	--ssl-mode=PREFERRED	- default
    	--ssl-mode=REQUIRED	- clients require an encrypted connection and fail if one cannot be established.
    	--ssl-mode=DISABLED	- clients use an unencrypted connection.
    	--ssl-mode=VERIFY_CA	- require an encrypted connection and perform verification against the server CA certificate 
    	--ssl-mode=VERIFY_IDENTITY	-  also perform verification against the server host name in its certificate
    The following options on the client side identify the certificate and key files clients use when establishing encrypted connections to the server.
    	shell> mysql --ssl-ca=ca.pem \			- the CA certificate. If used, must specify the same certificate used by the server
           			--ssl-cert=client-cert.pem \	- the client public key certificate
           			--ssl-key=client-key.pem	- the client private key
    A client can determine whether the current connection with the server uses encryption from the ssl_cipher status variable.
    	SHOW STATUS LIKE 'ssl_cipher';
    It is also possible to connect securely from within an SSH connection to the MySQL server host.


    Data encryption

    Encryption functions

    Many encryption and compression functions return strings containing arbitrary byte values and should be stored in a VARBINARY or BLOB column. This will avoid potential problems with trailing space removal or character set conversion that would change data values, if a nonbinary column (CHAR, VARCHAR, TEXT) is used.

    Some encryption functions return strings of ASCII characters - MD5(), SHA(), SHA1(), SHA2(), STATEMENT_DIGEST(), STATEMENT_DIGEST_TEXT(). Their return value has a character set and collation determined by the character_set_connection and collation_connection variables. This is a nonbinary string unless the character set is binary.

    AES_ENCRYPT() and AES_DECRYPT() implement encryption and decryption of data using the official AES (Advanced Encryption Standard) algorithm. The AES standard permits various key lengths. By default these functions implement AES with a 128-bit key length and key lengths of 196 or 256 bits can also be used. The key length is a trade off between performance and security.
    	AES_ENCRYPT(str, key_str)
    	AES_DECRYPT(crypt_str, key_str)
    AES_ENCRYPT() encrypts a string using the key string key_str and returns a binary string containing the encrypted output. AES_DECRYPT() decrypts the encrypted string using the key string key_str and returns the original plaintext string. If either function argument is NULL, the function returns NULL.

    The str and crypt_str arguments can be of any length and padding is automatically added to str so it is a multiple of a block as required by block-based algorithms such as AES. This padding is automatically removed by the AES_DECRYPT() function. The length of crypt_str can be calculated using this formula
    	16 * (trunc(string_length / 16) + 1)
    For a key length of 128 bits, the most secure way to pass a key to the key_str argument is to create a truly random 128-bit value and pass it as a binary value. For e.g
    	INSERT INTO t VALUES (1,AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
    A passphrase can be used to generate an AES key by hashing the passphrase. For e.g
    	INSERT INTO t VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));
    The COMPRESS() functiom compresses a string and returns the result as a binary string and requires MySQL to have been compiled with a compression library such as zlib. Otherwise, the return value is always NULL. The compressed string can be uncompressed with UNCOMPRESS().
    	SELECT LENGTH(COMPRESS(REPEAT('a',1000)));	- returns 21
    The MD5() function calculates an MD5 128-bit checksum for the string. The value is returned as a string of 32 hexadecimal digits or NULL if the argument was NULL. The return value can be used as a hash key.
    	SELECT MD5('testing');	- 'ae2b1fca515949e5d54fb22b8ed95575'

    Tablespace encryption

    Tablespace encryption uses a two tier encryption key architecture, consisting of a master encryption key and tablespace keys. When a tablespace is encrypted, a tablespace key is encrypted and stored in the tablespace header. When an application or authenticated user wants to access encrypted tablespace data, InnoDB uses a master key to decrypt the tablespace key. The decrypted version of a tablespace key never changes, but the master key can be changed as required (master key rotation).

    Tablespace encryption relies on a keyring plugin for master encryption key management. The keyring_file plugin is available in all mysql editions and stores keyring data in a file local to the server host. Additional keyring plugins are offered in the Enterprise edition.

    Enabling tablespace encryption

  • A keyring plugin must be installed and configured. Keyring plugin installation is performed at startup using the early-plugin-load option and it ensures that the plugin is available prior to initialization of the InnoDB storage engine.

    The keyring_file plugin library file base name is keyring_file. The file name suffix differs per platform (.so for Unix-like systems, .dll for Windows).
    	[mysqld]
    	early-plugin-load=keyring_file.so
    	keyring_file_data=/usr/local/mysql/mysql-keyring/keyring
    	
    	SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';	- check plugin status
  • To enable/disable encryption for a file-per-table tablespace
    	CREATE TABLE t1 (c1 INT) ENCRYPTION='Y';
    	ALTER TABLE t1 ENCRYPTION='Y';
    	ALTER TABLE t1 ENCRYPTION='N';
  • The master encryption key should be rotated periodically. Master key rotation is an atomic, instance-level operation. Each time the master encryption key is rotated, all tablespace keys in the MySQL instance are re-encrypted and saved back to their respective tablespace headers. If master key rotation is interrupted by a server failure, InnoDB rolls the operation forward on server restart.
    	ALTER INSTANCE ROTATE INNODB MASTER KEY;	- rotate the master encryption key
    Master key rotation supports concurrent DML but it cannot be run concurrently with tablespace encryption operations and locks are taken to prevent conflicts that could arise from concurrent execution.

    The keyring

    The InnoDB storage engine uses the keyring to store its key for tablespace encryption.
    	SHOW GLOBAL VARIABLES LIKE 'keyring_file_data';
    At plugin startup, if keyring_file_data specifies a file that does not exist, the keyring_file plugin attempts to create it and writes a message to the log if the file cannot be accessed or created.

    Once the keyring_file plugin has created its data file and started to use it, the file should not be removed. InnoDB uses the file to store the master key used to decrypt the data in tables that use InnoDB tablespace encryption. Loss of the file will cause data in such tables to become inaccessible. It is permissible to rename or move the file, as long as the value of keyring_file_data is changed to match.

    Keyring operations are transactional. The plugin uses a backup file during write operations to ensure that it can roll back to the original file if an operation fails. The backup file has the same name as the value of the keyring_file_data variable with a suffix of .backup.

    MySQL Enterprise Transparent Data Encryption (TDE)

    MySQL Enterprise TDE(Transparent Data Encryption) enables data-at-rest encryption by encrypting the physical files of the database. Data is encrypted automatically in real time prior to writing to storage and decrypted when read from storage.

    Back



    HIGH-AVAILABILITY/SCALABILITY

    Availability refers to the ability to cope with and recover from failures on the host, including failures of MySQL, the OS, or the hardware and maintenance activity that may otherwise cause downtime. Scalability refers to the ability to spread both the database and the load of application queries across multiple MySQL servers.

    Replication

    Replication enables data from one MySQL server (master) to be replicated to one or more servers (slaves). MySQL replication is asynchronous by default and slaves do not need to be connected permanently to receive updates from the master. Depending on the configuration, all databases, selected databases or even selected tables can be replicated.

    Replication is based on the master server keeping track of all changes to its databases in its binary log. Each slave that connects to the master requests a copy of the binary log i.e pulls the data from the master (rather than the master pushing the data to the slave) and executes the events from the binary log that it receives. Each slave is able to read and update the copy of the database at its own pace and can start and stop the replication process at will without affecting the ability to update to the latest database status on either the master or slave side.

    MySQL replication capabilities are implemented using three threads, one on the master server and two on the slave:

  • Binlog dump thread - The master creates a thread to send the binary log contents to a slave when the slave connects, which can be identified in the output of SHOW PROCESSLIST as the Binlog Dump thread. If there are no Binlog Dump threads on a master server, replication is not running i.e no slaves are currently connected.

    Binlog dump thread states: Sending binlog event to slave - Binary logs consist of events which is usually an update plus some other information. The thread has read an event from the binary log and is now sending it to the slave
    Finished reading one binlog; switching to next binlog - The thread has finished reading a binary log file and is opening the next one to send to the slave
    Master has sent all binlog to slave; waiting for more updates - The thread is idle, waiting for new events
    Waiting to finalize termination - A brief state that occurs as the thread is stopping
  • Slave I/O thread - When a START SLAVE statement is issued on a slave server, the slave creates an I/O thread, which connects to the master and asks to send the updates recorded in its binary logs, which are written to a relay log in the slave.

    Slave I/O thread states: Waiting for master update - The initial state before connecting to the master
    Requesting binlog dump - A brief state that occurs after connecting to the master. The thread sends to the master a request for the contents of its binary logs, starting from the requested file name and position
    Waiting for master to send event - The thread has connected to the master and is waiting for binary log events to arrive. If the wait lasts for slave_net_timeout seconds, a timeout occurs and the thread makes an attempt to reconnect
    Queueing master event to the relay log - The thread has read an event and is copying it to the relay log so that the SQL thread can process it
    Waiting for slave mutex on exit - A state that occurs briefly as the thread is stopping
    The state of this thread is shown as Slave_IO_running in the output of SHOW SLAVE STATUS or as Slave_running in the output of SHOW STATUS.

  • Slave SQL thread - The slave creates an SQL thread to read the relay log that is written by the slave I/O thread and execute the events contained therein

    Slave SQL thread states: Reading event from the relay log - The thread has read an event from the relay log for processing
    Slave has read all relay log; waiting for more updates - The thread has processed all events and is now waiting for the I/O thread to write new events
    Killing slave - The thread is processing a STOP SLAVE statement
    Slave relay log

    The relay log, like the binary log, consists of a set of numbered files containing events that describe database changes, and an index file that contains the names of all used relay log files. Relay log files have the same format as binary log files and can be read using mysqlbinlog.

    By default, relay log file names have the form host_name-relay-bin.nnnnnn in the data directory. The slave uses an index file ( default name - host_name-relay-bin.index in the data directory) to track the relay log files currently in use. The default relay log and index file names can be overridden with the --relay-log and --relay-log-index server options.

    The SQL thread automatically deletes each relay log file after it has executed all events in the file and no longer needs it.
    	SHOW GLOBAL variables LIKE '%relay%';
    		relay_log	- base name for the relay log
    		relay_log_index	- relay log index file

    Configuring replication

    The CHANGE MASTER TO/CHANGE REPLICATION SOURCE TO statement configures/changes the parameters that a slave/replica uses for connecting to the master, for reading the master binary log and reading the slave relay log. It also updates the contents of the master info and relay log info repositories. It needs the REPLICATION_SLAVE_ADMIN or SUPER privilege.

    The optional FOR CHANNEL channel clause specifies the replication channel the statement applies to and is used to add a new channel or modify an existing channel.
    	CHANGE MASTER TO MASTER_HOST = host, MASTER_PORT = TCP/IP port, MASTER_USER = user, MASTER_PASSWORD = pwd, MASTER_AUTO_POSITION = 1 [FOR CHANNEL channel1];
     		MASTER_AUTO_POSITION = 1	- connect using GTID-based protocol (default = 0)
    		MASTER_LOG_FILE/MASTER_LOG_POS	- coordinates the slave I/O thread should begin reading from the master for binary log file position based replication
    CHANGE MASTER TO deletes all relay log files and starts a new one unless either the slave SQL thread or I/O thread is running.

    START SLAVE starts the slave threads and requires the REPLICATION_SLAVE_ADMIN or SUPER privilege.
    	START SLAVE;	- start both threads
    	START SLAVE IO_THREAD;
    	START SLAVE SQL_THREAD;

    The log_slave_updates option makes a slave write updates received from a master to its own binary log. Binary logging must also be enabled on the slave. This enables replication servers to be chained i.e a slave can be a master of another slave.
    	SHOW GLOBAL VARIABLES LIKE 'log_slave_updates';
    GTID-based replication

    A global transaction identifier (GTID) is a unique identifier created and associated with each transaction committed on the server of origin (master). The GTID (serveruuid:txnid) is unique across all servers in a given replication setup. A GTID set comprises one or more single GTIDs or ranges of GTIDs.
    	3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
    	3E11FA47-71CA-11E1-9E33-C80AA9429562:1-3:11:47-49
    When using GTIDs, each transaction can be identified and tracked and it is not necessary to refer to log files and positions when starting a new slave or failing over to a new master, which greatly simplifies these tasks. Because GTID-based replication is completely transaction-based, it is simple to determine whether masters and slaves are consistent.

    The auto-skip function for GTIDs ensures that a transaction committed on the master can be applied only once on the slave guaranteeing consistency. Once a transaction with a given GTID has been committed on a given server, any attempt to execute a subsequent transaction with the same GTID is ignored by that server and no error is raised.
    	SHOW GLOBAL variables LIKE 'gtid_%';
    		gtid_mode	- whether gtid-based logging is enabled
    		gtid_executed	- all transactions executed on the server
    		gtid_owned	- for internal use, list of GTIDs currently in use with the ids of threads that own them
    		gtid_purged	- set of all transactions purged from the binary log, subset of gtid_executed
    		
    	SHOW variables LIKE 'gtid_%';
    		gtid_next	- how the next gtid value is obtained (Default - Automatic)
    The variable gtid_executed contains the set of all transactions executed on the server and GTIDs that have been set by a SET gtid_purged statement and is the same as the value of the Executed_Gtid_Set column in the output of SHOW MASTER STATUS and SHOW SLAVE STATUS. When the server starts gtid_executed is initialized by reading the binary logs. GTIDs are then added to the set as transactions are executed or if any SET gtid_purged statement is executed.

    The following categories of GTIDs are in gtid_purged
  • GTIDs of replicated transactions that were committed with binary logging disabled on the slave
  • GTIDs of transactions that were written to a binary log file that has now been purged
  • GTIDs that were added explicitly to the set by the statement SET @@GLOBAL.gtid_purged

    The set of transactions that can be found in the binary logs at any given time is equal to
    	select GTID_SUBTRACT(@@GLOBAL.gtid_executed, @@GLOBAL.gtid_purged);
    The system table mysql.gtid_executed is used to preserve the assigned GTIDs of all the transactions applied on a server, except those that are stored in a currently active binary log file. A row in this table contains the UUID of the server and the starting and ending transaction IDs of the GTID set. These two values are the same for a row referencing only a single GTID.
    	select * from mysql.gtid_executed;
    Compression of the mysql.gtid_executed table is performed by a dedicated foreground thread named thread/sql/compress_gtid_table, which combines multiple rows for the same UUID into a single row.
    	SHOW GLOBAL variables like 'gtid_executed_compression_period';	- default 1000 (transactions)
    GTID Auto-positioning

    When GTIDs are in use, all the information that the slave needs for synchronizing with the master is obtained directly from the replication data stream by enabling the MASTER_AUTO_POSITION option.

    When a slave has GTIDs enabled and the MASTER_AUTO_POSITION option enabled, auto-positioning is activated for connection to the master. The master must have GTID_MODE=ON for the connection to succeed. In the initial handshake, the slave sends a GTID set containing the transactions that it has already received, committed or both. This GTID set is equal to the union of the set of GTIDs in the gtid_executed variable (@@GLOBAL.gtid_executed) and the set of GTIDs recorded in the Performance Schema replication_connection_status table as received transactions (the result of SELECT received_transaction_set FROM performance_schema.replication_connection_status).

    The master responds by sending all transactions recorded in its binary log whose GTID is not included in the GTID set sent by the slave. This exchange ensures that the master only sends the transactions with a GTID that the slave has not already received or committed. If the slave receives transactions from more than one master, as in the case of a diamond topology, the auto-skip function ensures that the transactions are not applied twice.

    If any of the transactions to be sent by the master have been purged from the master's binary log or added to the set of GTIDs in the gtid_purged system variable by another method, the master sends an error the slave and replication does not start. The GTIDs of the missing purged transactions are identified and listed in the master's error log in a warning message. To recover from this error, the missing transactions need to be replicated from another source or the slave needs to be replaced by a new slave created from a more recent backup.

    Configuring GTID-based replication: 1. Stop both servers
    2. Restart both servers with GTIDs enabled
    	[mysqld]
    	gtid_mode=ON
    	log-bin
    	enforce-gtid-consistency
    	server-id=1	(2 for slave)
    	log-slave-updates	(for slave)
    3. Direct the slave to use the master and start replicating
    	CHANGE MASTER TO MASTER_HOST='localhost', MASTER_PORT=3306, MASTER_USER='repluser', MASTER_PASSWORD='pwd', MASTER_AUTO_POSITION=1;
    	START SLAVE;

    Multi-threaded replication

    In a single-threaded slave, a single thread applies replication events serially. Transactions utilize separate CPU cores on the master, while the slave uses just one CPU core to execute the replication events. A multi-threaded slave (MTS) provides parallel execution by using multiple worker threads and a coordinator thread to manage them. The way which transactions are distributed among applier threads is configured by slave_parallel_type. Setting slave_parallel_workers to a number greater than 0 creates an MTS with this number of applier threads. When set to 0 (the default) parallel execution is disabled and the slave uses a single applier thread.

    Setting slave_parallel_workers has no immediate effect and the state of the variable applies on all subsequent START SLAVE statements. The optimum number of applier threads depends on the workload and too many threads will increase the synchronization effort between threads and may bring reduced benefit.
    	SHOW GLOBAL VARIABLES LIKE 'slave%';
    		slave_parallel_type - 	policy used to decide which transactions are allowed to execute in parallel on the slave
    			DATABASE - transactions that update different databases are applied in parallel
    			LOGICAL_CLOCK - transactions that are part of the same binary log group commit on a master are applied in parallel
    		slave_parallel_workers	- number of slave applier threads for executing replication transactions in parallel (default = 0)
    		slave_preserve_commit_order	- ensures that transactions are committed in the same order as they appear in the relay log
    Once a multi-threaded slave has been started, transactions can begin to execute in parallel. With slave_preserve_commit_order enabled, the executing thread waits until all previous transactions are committed before committing. While the slave thread is waiting for other workers to commit their transactions it reports its status as 'Waiting for preceding transaction to commit'. Enabling this mode on an MTS ensures that it never enters a state that the master was not in.
    	select * from performance_schema.replication_applier_status_by_coordinator;	- status of the coordinator thread
    	select * from performance_schema.replication_applier_status_by_worker;	- status of worker threads

    Replication channels

    In MySQL multi-source replication, a replica opens multiple replication channels, one for each source. The replication channels represent the path of transactions flowing from a source to the replica. Each replication channel has its own receiver (I/O) thread, one or more applier (SQL) threads, and relay log. When transactions from a source are received by a channel's receiver thread, they are added to the channel's relay log file and passed through to the channel's applier threads, enabling each channel to function independently.

    The maximum number of channels that can be created on one replica in a multi-source replication topology is 256. A multi-source replica can also be set up as a multi-threaded replica by setting slave_parallel_workers to a value greater than 0. Each channel on the replica has the specified number of applier threads, plus a coordinator thread to manage them. The number of applier threads cannot be configured for individual channels.

    To enable replication operations to act on individual replication channels, the FOR CHANNEL channel clause can be used with the following replication statements
    	CHANGE REPLICATION SOURCE TO/CHANGE MASTER TO
    	START/STOP/RESET REPLICA/SLAVE
    	SHOW RELAYLOG EVENTS
    	FLUSH RELAY LOGS
    	SHOW REPLICA STATUS/SHOW SLAVE STATUS

    Filtered replication

    CHANGE REPLICATION FILTER sets one or more replication filtering rules on the replica in the same way as starting the replica mysqld with replication filtering options such as --replicate-do-db or --replicate-wild-ignore-table. CHANGE REPLICATION FILTER requires the SUPER privilege.

    Options for CHANGE REPLICATION FILTER
  • REPLICATE_DO_DB/REPLICATE_IGNORE_DB - include/exclude updates based on database name (equivalent to --replicate-do-db/--replicate-ignore-db)
  • REPLICATE_DO_TABLE/REPLICATE_IGNORE_TABLE - include/exclude updates based on table name (--replicate-do-table/--replicate-ignore-table)
  • REPLICATE_WILD_DO_TABLE/REPLICATE_WILD_IGNORE_TABLE - include/exclude updates based on wildcard pattern matching table name (--replicate-wild-do-table/--replicate-wild-ignore-table)
  • REPLICATE_REWRITE_DB - perform updates on replica after substituting database name (--replicate-rewrite-db)

    Names of tables and database not containing any special characters need not be quoted. Values used with REPLICATION_WILD_TABLE and REPLICATION_WILD_IGNORE_TABLE are string expressions, possibly containing wildcard characters and must be quoted.
    	CHANGE REPLICATION FILTER REPLICATE_DO_DB = (db1,db2), REPLICATE_IGNORE_DB = (db3);
    	CHANGE REPLICATION FILTER REPLICATE_IGNORE_TABLE = (db1.t1) for channel 'channel_1';	- channel specific replication filter
    	CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.old%');
    	CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('db1.new%', 'db2.new%');
    	CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));	- rewrites statements on db1 on the source to db2 on the replica
    	CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2), (db3, db4));
    The CHANGE REPLICATION FILTER statement replaces replication filtering rules only for the filter types and replication channels affected by the statement, and leaves other rules and channels unchanged. For unsetting all filters of a given type, the filter's value can be set to an explicitly empty list.
    	CHANGE REPLICATION FILTER REPLICATE_DO_DB = (), REPLICATE_IGNORE_DB = (); - removes all existing REPLICATE_DO_DB and REPLICATE_IGNORE_DB rules

    Monitoring replication

    On the master
    	SHOW SLAVE HOSTS;	- list of slaves registered with the master
    	SHOW MASTER STATUS;	- status info about the binary log files of the master
    On the slave
    	SHOW GLOBAL STATUS LIKE 'Slave_running';	- ON if the machine is a slave and both the I/O and SQL threads are running
    
    	SHOW SLAVE STATUS \G
    		Master_Log_File/Read_Master_Log_Pos - master binary log file and position up to which the I/O thread has read
    		Relay_Master_Log_File/Exec_Master_Log_Pos -  master binary log file and position up to which the SQL thread has executed events
    		Seconds_Behind_Master - time difference between SQL and IO threads
    		Retrieved_Gtid_Set	- set of GTIDs corresponding to all transactions received by the slave. When all relay logs are purged by 
    					RESET SLAVE or CHANGE MASTER TO, the set is cleared. When relay_log_purge = 1, the newest relay log is always kept 
    					and the set is not cleared
    		Executed_Gtid_Set	- set of GTIDs written in the binary log, same as the Executed_Gtid_Set value in SHOW MASTER STATUS
    Handling errors

    The below statement skips the next N events from the master and is useful for recovering from replication stops caused by a statement.
    	SET GLOBAL sql_slave_skip_counter = N;
    The statement is valid only when the slave threads are not running, else it produces an error. When the skipped event is in the middle of a transaction event group, the slave continues to skip events until it reaches the end of the group and starts execution from the next event group.

    The sql_slave_skip_counter is not usable when gtid-based replication is in vogue. To skip statements when gtid_mode=ON, empty transactions need to be injected.
    	STOP SLAVE;
    	SET gtid_next='eacc5096-be12-11e6-99cf-e839355808e3:1406';	- transaction to skip
    	BEGIN; COMMIT;
    	SET gtid_next='AUTOMATIC';
    	START SLAVE;
    After the START SLAVE the slave checks that the transaction is already in its own binary log and considers it as having been executed.


    Stopping/resetting replication

    A slave can be removed from the replication setup by issuing a STOP SLAVE and then a RESET SLAVE ALL command.

    The RESET SLAVE statement makes the slave forget its replication position in the master's binary log and is meant to be used for a clean start. It clears the master info and relay log info repositories, deletes all the relay log files and starts a new relay log file. RESET SLAVE does not change the values of gtid_executed or gtid_purged.

    The RESET SLAVE statement requires the RELOAD privilege and the running replication threads must be stopped using STOP SLAVE before issuing RESET SLAVE.
    	STOP SLAVE;	- stops the slave threads
    	STOP SLAVE IO_THREAD;
    	STOP SLAVE SQL_THREAD;
    
    	RESET SLAVE;
    	RESET SLAVE ALL;
    RESET SLAVE does not change any replication connection parameters such as master host, port, user or password. When master_info_repository=TABLE is set on the server, the connection parameters are preserved in the crash-safe table mysql.slave_master_info as part of the RESET SLAVE operation. They are also retained in memory. In the event of a server crash or deliberate restart after issuing RESET SLAVE but before issuing START SLAVE, the parameters are retrieved from the table and reused.

    When master_info_repository=FILE is set on the server, replication connection parameters are only retained in memory and if the slave mysqld is restarted after issuing RESET SLAVE deliberately or due to a crash, they are lost. A CHANGE MASTER TO statement must be issued after the server start to respecify the parameters before issuing START SLAVE.

    Connection parameters are reset by RESET SLAVE ALL.

    RESET MASTER deletes all binary log files and the binary log index file returning the master to its state before binary logging was started. RESET MASTER also resets the GTID execution history by clearing and setting the values of the gtid_purged and gtid_executed system variables to an empty string and also clears the mysql.gtid_executed table.
    	RESET MASTER;
    The sql_log_bin variable can be set to OFF for a session to temporarily disable binary logging while making changes to the master that should not be replicated to the slave.
    	SET SESSION sql_log_bin=OFF;
    Master/Slave shutdowns during replication

    It is safe to shut down a master server and restart it later. When a slave loses its connection to the master, it tries to reconnect immediately and retries periodically. The default is every 60 seconds and can be changed with the CHANGE MASTER TO statement.

    An unclean shutdown/crash on the master can result in the master binary log having a final position less than the most recent position read by the slave, due to the master binary log file not being flushed. This can cause the slave not to be able to replicate when the master comes back up. Setting sync_binlog=1 helps to minimize this problem.

    Shutting down a slave cleanly is safe because it keeps track of where it left off. Unclean shutdowns might produce problems, especially if the disk cache was not flushed to disk before the problem occurred.

    Switching masters during failover

    Slaves can be run with binary logging enabled (the default) and if GTIDs are not used for replication, then also with --skip-log-slave-updates. In this way, the slave is ready to become a master without restarting mysqld. A restart will be required to enable binary logging.

    Back



    Group replication

    MySQL group replication is a MySQL Server plugin that enables creating elastic, highly-available, fault-tolerant replication topologies. Groups can operate in a single-primary mode with automatic primary election, where only one server accepts updates at a time. Alternatively, groups can be deployed in multi-primary mode, where all servers can accept updates, even if they are issued concurrently, with applications having to workaround the limitations of such deployments.

    In multi-primary mode, all read-write (RW) transactions commit only after they have been approved by the group. When a transaction is ready to commit at the originating server, the server atomically broadcasts the write values (rows changed) and the correspondent write set (unique identifiers of the rows that were updated). Then a global total order is established for that transaction. This means that all servers receive the same set of transactions in the same order. As a consequence, all servers apply the same set of changes in the same order and remain consistent.

    Conflicts are detected by inspecting the write sets of two different and concurrent transactions, in a process called certification. The resolution procedure states that the transaction that was ordered first commits on all servers, whereas the transaction ordered second aborts, and is rolled back on the originating server and dropped by the other servers in the group.


    MySQL NDB Cluster

    MySQL Cluster is a high-availability, high-redundancy version of MySQL adapted for the distributed computing environment. MySQL Cluster integrates the standard MySQL server with an in-memory clustered storage engine called NDB (Network DataBase, also called NDBCLUSTER) to enable running several computers with MySQL servers and other software in a cluster.

    A MySQL Cluster consists of a set of computers, known as hosts, each running one or more processes. These processes, known as nodes, may include MySQL servers (for access to NDB data), data nodes (for storage of the data), one or more management servers, and possibly other specialized data access programs.

    NDB Cluster process types
  • Management node - performs administrative tasks such as stopping individual data nodes, querying node and cluster status, and making backups. Executable: ndb_mgmd
  • Single-threaded data node - Stores data and executes queries. Executable: ndbd
  • Multi threaded data node - Stores data and executes queries with multiple worker threads executing in parallel. Executable: ndbmtd
  • SQL node - MySQL server for executing SQL queries against NDB. Executable: mysqld
  • API node - A client accessing data in NDB by means of the NDB API or other low-level client API, rather than by using SQL
  • Management client - Not needed to run the cluster but provides commands for checking cluster status, starting backups and other functions. Executable: ndb_mgm
    Each NDB Cluster host computer must have the correct executable programs installed.

    Auto-Sharding

    MySQL Cluster uses automatic sharding (partitioning) to scale out read and write operations and can be accessed via SQL and Non-SQL (NoSQL) APIs.

    Unlike other sharded databases, users do not lose the ability to perform JOIN operations, sacrifice ACID-guarantees or referential integrity (Foreign Keys) when performing queries and transactions across shards. MySQL Cluster also replicates across data centers for disaster recovery and global scalability. Using its conflict handling mechanisms, each cluster can be active, accepting updates while maintaining consistency across locations.

    Data nodes

    A data node (ndbd or ndbmtd process) stores one or more replicas i.e copies of the partitions assigned to the node group of which the node is a member. Each data node should be located on a separate computer.

    Node group

    A node group consists of one or more nodes, and stores partitions, or sets of replicas. The number of node groups in an NDB Cluster is not directly configurable; it is a function of the number of data nodes and of the number of replicas (NoOfReplicas config parameter).
    	[# of node groups] = [# of data nodes]/ NoOfReplicas
    Partition

    This is a portion of the data stored by the cluster. Each node is responsible for keeping at least one copy (replica) of any partitions assigned to it available to the cluster.

    Replica

    This is a copy of a cluster partition. Each node in a node group stores a replica. The number of replicas is equal to the number of nodes per node group.


    NDB Cluster installation

    Initial configuration of NDB Cluster

    Each data node or SQL node requires a my.cnf file that provides two pieces of information: a connection string to find the management node and a line telling the MySQL server on this host to enable the NDBCLUSTER storage engine. The configuration file should be located in the /etc directory
    	$> vi /etc/my.cnf
    	
    	[mysqld]
    	ndbcluster	# run NDB storage engine
    
    	[mysql_cluster]
    	ndb-connectstring=198.51.100.10		# location of management server
    The management node needs a config.ini file telling it how many fragment replicas to maintain, how much memory to allocate for data and indexes on each data node, where to find the data nodes, where to save data to disk on each data node and where to find any SQL nodes.
    	$> mkdir /var/lib/mysql-cluster
    	$> cd /var/lib/mysql-cluster
    	$> vi config.ini
    
    
    	[ndbd default]
    	# Options affecting ndbd processes on all data nodes
    	NoOfReplicas=2    # Number of fragment replicas
    	DataMemory=98M    # How much memory to allocate for data storage
    
    	[ndb_mgmd]
    	# Management process options
    	HostName=198.51.100.10          # management node
    	DataDir=/var/lib/mysql-cluster  # directory for management node log files
    
    	[ndbd]
    	# (one [ndbd] section per data node)
    	HostName=198.51.100.40          # Hostname or IP address
    	NodeId=2                        # Node ID for this data node
    	DataDir=/usr/local/mysql/data   # directory for this data node's data files
    
    	[ndbd]
    	HostName=198.51.100.50          
    	NodeId=3                        
    	DataDir=/usr/local/mysql/data   
    
    	[mysqld]
    	# SQL node options
    	HostName=198.51.100.20          # Hostname or IP address
    	NodeId=4						# Node ID for this SQL node
    	
    	[mysqld]
    	HostName=198.51.100.30          
    	NodeId=5
    Initial startup of NDB Cluster

    Each cluster node process must be started separately on the host where it resides. The management node should be started first, followed by the data nodes and then finally by any SQL nodes.

    On the management host, following command must be issued from the system shell to start the management node process
    	$> ndb_mgmd --initial -f /var/lib/mysql-cluster/config.ini
    The first time that it is started, ndb_mgmd must be told where to find its configuration file, using the -f or --config-file option. This option requires that --initial or --reload to be specified.

    On each of the data node hosts, this command must be run to start the ndbd process
    	$> ndbd
    The startup script must be used to start the MySQL server process on the SQL nodes.

    The cluster should now be operational and can be tested by invoking the ndb_mgm management node client. The output looks as below
    	$> ndb_mgm
    	-- NDB Cluster -- Management Client --
    	ndb_mgm> SHOW
    	Connected to Management Server at: localhost:1186
    	Cluster Configuration
    	---------------------
    	[ndbd(NDB)]     2 node(s)
    	id=2    @198.51.100.40  (Version: 8.0.34-ndb-8.0.34, Nodegroup: 0, *)
    	id=3    @198.51.100.50  (Version: 8.0.34-ndb-8.0.34, Nodegroup: 0)
    
    	[ndb_mgmd(MGM)] 1 node(s)
    	id=1    @198.51.100.10  (Version: 8.0.34-ndb-8.0.34)
    
    	[mysqld(API)]   1 node(s)
    	id=4    @198.51.100.20  (Version: 8.0.34-ndb-8.0.34)
    	id=4    @198.51.100.30  (Version: 8.0.34-ndb-8.0.34)
    The SQL node is referenced here as [mysqld(API)], which reflects the fact that the mysqld process is acting as an NDB Cluster API node. The NDB cluster should now be ready to handle tables and data.

    Caching of configuration data

    The management server caches the configuration the first time it is started and thereafter the global configuration file is read only when one of the following conditions is true
  • The --initial option is used to start the management server. The global configuration file is re-read, any existing cache files are deleted and a new cache is created
  • The --reload option is used while starting which causes the management server to compare its cache with the global configuration file and if they differ, a new cache is created. Any existing configuration cache is preserved, but not used. If the cache and the file contain the same configuration data, then the existing cache is used and no new cache is created
  • The management server is started using --config-cache=FALSE, which disables --config-cache (enabled by default) and can be used to bypass configuration caching altogether and configuration data is always read from the config.ini file
  • No configuration cache is found. In this case, the management server reads the global configuration file and creates a cache containing the same data as found in the file

    The management server by default creates configuration cache files in a directory named mysql-cluster in the MySQL installation directory. This can be overridden at runtime by starting the management server with the --configdir option. Configuration cache files are binary files named according to the pattern ndb_node_id_config.bin.seq_id, where node_id is the management server's node ID in the cluster, and seq_id is a cache identifier. Cache files are numbered sequentially using seq_id, in the order in which they are created. The management server uses the latest cache file as determined by the seq_id. It is possible to roll back to a previous configuration by deleting later configuration cache files or by renaming an earlier cache file so that it has a higher seq_id.

    NDB Cluster management client

    In addition to the central configuration file, a cluster may also be controlled through a command-line interface available through the management client ndb_mgm which is the primary administrative interface to a running cluster.

    The client has the following commands

    CONNECT connection-string

    Connects to the management server indicated by the connection string. If the client is already connected to this server, the client reconnects

    CREATE NODEGROUP nodeid[, nodeid, ...]

    Creates a new NDB Cluster node group and causes data nodes to join it. This command is used after adding new data nodes online to a cluster and causes them to join a new node group and begin participating fully in the cluster. The command takes as its sole parameter a comma-separated list of node IDs of the nodes just added and started that are to join the new node group. The list must contain no duplicate IDs and the number of nodes in the list must be the same as the number of nodes in each node group that is already part of the cluster (each NDB Cluster node group must have the same number of nodes) i.e. if the NDB Cluster consists of 2 node groups having 2 data nodes each, then the new node group must also have 2 data nodes

    The node group ID of the new node group created by this command is determined automatically and is always the next highest unused node group ID in the cluster and it is not possible to set it manually.

    DROP NODEGROUP nodegroup_id

    Drops the NDB Cluster node group with the given nodegroup_id. DROP NODEGROUP acts only to remove the data nodes in the effected node group from that node group. It does not stop data nodes, assign them to a different node group or remove them from the cluster's configuration. A data node that does not belong to a node group is indicated in the output of the SHOW command with no nodegroup in place of the node group ID as below
    	id=3    @10.100.2.67  (8.0.34-ndb-8.0.34, no nodegroup)
    The command works only when all data nodes in the node group to be dropped are completely empty of any table data and table definitions.

    HELP

    Displays information on all available commands.

    QUIT, EXIT

    Terminates the management client.

    SHOW

    Displays basic information about the cluster and cluster nodes. For all nodes, the output includes the node's ID, type, and NDB software version. If the node is connected, its IP address is also shown; otherwise the output shows not connected, accepting connect from ip_address, with any host used for nodes that are permitted to connect from any address.

    In addition, for data nodes, the output includes starting if the node has not yet started and shows the node group of which the node is a member. If the data node is acting as the master node, this is indicated with an asterisk (*).

    SHUTDOWN

    Shuts down all cluster data nodes and management nodes. It does not shut down any SQL nodes or API nodes that are connected to the cluster.

    node_id STATUS

    Displays status information for the data node identified by node_id (or for all data nodes). Possible node status values include UNKNOWN, NO_CONTACT, NOT_STARTED, STARTING, STARTED, SHUTTING_DOWN and RESTARTING. The output also indicates when the cluster is in single user mode.

    Back



    InnoDB Cluster

    An InnoDB Cluster consists of at least three MySQL Server instances and it provides high-availability and scaling features. InnoDB Cluster uses the following MySQL technologies
  • MySQL Shell, which is an advanced client and code editor for MySQL. MySQL Shell includes AdminAPI which enables configuring and administering an InnoDB Cluster and removes the need to work directly with Group Replication in InnoDB clusters
  • Group Replication, which enables a set of MySQL instances to replicate data and provide high-availability. InnoDB Cluster provides an alternative, easy to use programmatic way to work with Group Replication
  • MySQL Router, a lightweight middleware that provides transparent routing between the application and InnoDB Cluster
    		Client app	MySQL shell(cluster admin) <------------
    			|	|					|
    			|	|					|
    			V   	V					|  MySQL Admin API
    			MySQL Router					|
    				|	 _______________________________|
    				|	|
    				|	|
    	 -----------------------+-----------------------------------------------
    	|			|	|			MySQL Servers	|
    	|			V	V					|
    	|	 --------------------------------				|		
    	|	|	Primary instance (R/W)   |				|
    	|   	 --------------------------------				|
    	|		|		| 					|	
    	|		|		| 					|	
    	|		|		| Group					|
    	|		|		| replication				|	
    	|		V		V					|		
    	|	Secondary		Secondary				|
    	|	instance1(R/O)		instance2(R/O)				|
    	|									| High-availability cluster
    	 -----------------------------------------------------------------------
    	
    The AdminAPI can be accessed through the dba global variable and its associated methods. The dba variable's methods enable deploying, configuring and administering InnoDB clusters. For e.g, the dba.createCluster() method creates an InnoDB cluster.

    MySQL Shell enables connecting to servers over a socket connection, but AdminAPI does not support it and requires TCP connections to a server instance.

    MySQL Router

    MySQL Router is part of InnoDB cluster and is a lightweight middleware that provides transparent routing between applications and back-end MySQL Servers. It can be used for scalability by effectively routing database traffic to appropriate servers. The pluggable architecture also enables developers to extend MySQL Router for custom use cases.

    InnoDB Cluster is tightly integrated with MySQL Router and AdminAPI can be used to work with them together. MySQL Router can automatically configure itself based on an InnoDB Cluster, in a process called bootstrapping, which removes the need to configure routing manually. MySQL Router then transparently connects client applications to the InnoDB Cluster, providing routing and load-balancing for client connections.

    The steps for deploying MySQL Router with an InnoDB Cluster after configuring the cluster are:
  • Install MySQL Router
  • Bootstrap InnoDB Cluster and test - Bootstrapping automatically configures MySQL Router for an existing InnoDB Cluster by using --bootstrap and other command-line options. During bootstrap, Router connects to the cluster, fetches its metadata and configures itself for use. Bootstrapping is optional
  • Set up MySQL Router for automatic startup - system needs to be configured to automatically start MySQL Router when the host is rebooted, a process similar to how the MySQL server is configured to start automatically

    Back



    TOOLS/UTILITIES

    MySQL workbench

    MySQL workbench provides a graphical integrated tools environment for working with MySQL Servers and databases, including
  • Database and SQL development - using a visual editor

  • Database design & modeling - The workbench provides capabilities for creating and manipulating database models including:
    Create and manipulate a model graphically
    Reverse engineer a live database to a model
    Forward engineer a model to a script or live database
    Create and edit tables and insert data
  • Server configuration and administration - Performance statistics can be viewed in a graphical dashboard. Statistics shown include network status (Incoming and Outgoing network traffic and Client connections), MySQL status (Table open cache efficiency, SQL Statements Executed and counts per second for SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER and DROP statements) and InnoDB status (Usage, Reads and Writes).

  • Database migration - Enables the migration of ODBC-compliant databases to MySQL, using the Migration Wizard. The workbench converts tables and copies data but will not convert stored procedures, views or triggers.

  • Data export and import - The Table Data Export and Import Wizard supports import and export operations using CSV and JSON files. SQL Data Export and Import Wizard can be used to either export or import SQL generated from MySQL Workbench or with the mysqldump command. A result set in the visual SQL editor can be exported to file formats including CSV, JSON, HTML and XML.


    MySQL Enterprise monitor

    MySQL Enterprise Monitor is a web-based application designed to monitor one or more MySQL servers on a network or on a cloud service.

    MySQL Enterprise Monitor has the following components

  • MySQL Enterprise Monitor Agent - communicates with the MySQL instances and hosts that it monitors and collects variables, status and health information according to a defined schedule. The collection data is sent to MySQL Enterprise Service Manager for analysis and presentation. MySQL Enterprise Monitor Agent is typically installed on the same host as the monitored server

  • MySQL Enterprise Service Manager - analyzes, stores and presents the data collected by the agent. It also contains a built-in agent which is used to monitor the repository


    MySQL utilities

    MySQL utilities are command-line utilities that are used for maintaining and administering MySQL servers, that can be installed with the MySQL workbench or as a standalone package. They can be invoked from the command-line or from the workbench using the Tools -> Start shell for MySQL utilities option.

    Admin utilities

    mysqlbinlog - displays the events in the binary log files (also relay log files) in text format. The output from mysqlbinlog can be re-executed by using it as input to mysql to redo the statements in the log for recovery operations after an unexpected server exit. To execute the internal-use BINLOG statements used by mysqlbinlog, the user requires the BINLOG_ADMIN privilege or the REPLICATION_APPLIER privilege plus the appropriate privileges to execute each log event.

    mysqlbinlog can be used to read binary log files directly and apply them to the local MySQL server and can also read binary logs from a remote server by using the --read-from-remote-server option.

    	mysqlbinlog binlog.0000003	- display contents
    	mysqlbinlog --result-file out.txt binlog.0000003	- write output to file
    	mysqlbinlog -uuser -p -hhost  --read-from-remote-server --result-file out.txt binlog.000003	- read log from remote server
    Options
    --rawwrite events in raw(binary) format to output files
    --start-position=Nstart reading the binary log at the first event having a position equal to or greater than N. This option applies to the first log file named on the command line. Useful for point-in-time recovery
    --stop-never used with --read-from-remote-server to remain connected with the server. Otherwise mysqlbinlog exits when the last log file has been transferred from the server. --stop-never implies --to-last-log, so only the first log file to transfer needs to be named on the command line. --stop-never is commonly used with --raw to make a live binary log backup, but also can be used without --raw to maintain a continuous text display of log events as the server generates them
    --stop-position=Nstop reading the binary log at the first event having a position equal to or greater than N. This option applies to the last log file named on the command line. Useful for point-in-time recovery
    --to-last-log, -tdo not stop at the end of the requested binary log but continue printing until the end of the last binary log. This option requires --read-from-remote-server
    --verbosereconstruct row events as SQL statements

    The events in the output are preceded by header comments that provide additional information.
    	# at 141
    	#100309  9:28:36 server id 123  end_log_pos 245
    	Query thread_id=3350  exec_time=11  error_code=0
    In the first line, the number following at indicates the file offset, or starting position, of the event in the binary log file.

    The second line starts with a date and time indicating when the statement started on the server where the event originated. end_log_pos indicates where the next event starts (i.e the end position of the current event + 1).

    The output of mysqlbinlog can be piped into the mysql client to execute the events contained in the binary log.
    	shell> mysqlbinlog binlog.000001 | mysql -u root -p
    	shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p		- process multiple files
    Another approach to process multiple files is to write all the logs to a single file and then process it
    	shell> mysqlbinlog binlog.000001 >  /tmp/stmts.sql
    	shell> mysqlbinlog binlog.000002 >> /tmp/stmts.sql
    	shell> mysql -u root -p -e "source /tmp/stmts.sql"
    mysqldbcompare - Compares the objects and data from two databases to find differences
    	mysqldbcompare --server1=root:passwd@localhost:3306 --server2=root:passwd@localhost:3306 db1:db2 --run-all-tests	- compare databases db1 and db2 on the local server
    mysqldbcopy - Copies a database on a source server to a database on a destination server
    	mysqldbcopy --source=root:pass@localhost:3310 --destination=root:pass@localhost:3310 db1:db1_copy	- copy database db1 to db1_copy on the same server
    mysqldbexport - Exports metadata (object definitions) or data or both from one or more databases. mysqldbexport differs from mysqldump in that it can produce output in a variety of formats to make data extraction/transport much easier. It can export data in the format most suitable to an external tool or another MySQL server without the need to reformat the data
    	mysqldbexport --server=root@server1:3306 --format=csv db1 --export=data


    General utilities

    mysqlfrm - reads .frm files and produces equivalent create statements from the table definition found in the file
    	mysqlfrm --diagnostic  "C:\MySQL\DATA\tbl.frm"
    perror - displays the error message for MySQL or OS error codes
    	shell> perror errorcode

    MySQL Shell

    MySQL Shell is an advanced client and code editor for MySQL Server. In addition to the provided SQL functionality, similar to mysql, MySQL Shell provides scripting capabilities for JavaScript and Python and includes APIs for working with MySQL. MySQL Shell is a component that can be installed separately.

    MySQL Shell includes the following APIs implemented in JavaScript and Python which can be used to develop code that interacts with MySQL.
  • The X DevAPI enables developers to work with both relational and document data when MySQL Shell is connected to a MySQL server using the X Protocol. This enables MySQL to be used as a Document Store, sometimes referred to as 'using NoSQL'.
  • The AdminAPI enables database administrators to work with InnoDB Cluster, which provides an integrated solution for high availability and scalability using InnoDB based MySQL databases. The AdminAPI also includes support for InnoDB ReplicaSet, which enables administering a set of MySQL instances running asynchronous GTID-based replication in a similar way to InnoDB Cluster. Additionally, the AdminAPI makes administration of MySQL Router easier, including integration with both InnoDB Cluster and InnoDB ReplicaSet.

    MySQL Shell is available in two editions, the Community Edition and the Commercial Edition.

    Percona Toolkit

    Percona toolkit is a collection of advanced open source command-line tools that can be used for MySql administrative tasks.

  • pt-archiver - archives table rows into another table or a file
    	pt-archiver --source L=ON,h=host,D=db1,t=t1,i=ix_t1_date1,u=user,p=pwd --dest h=host,D=db2,u=user,p=pwd 
    		--where "date1 < DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 3 MONTH" --charset utf8  --limit 2000 --commit-each 
    		--progress 10000 --bulk-insert --bulk-delete --statistics
  • pt-diskstats - prints disk I/O statistics for GNU/Linux. It is similar to iostat, but it is interactive and more detailed
  • pt-duplicate-key-checker - finds duplicate indexes and foreign keys
  • pt-mysql-summary - summarizes the status and configuration of MySQL servers
  • pt-slave-restart - watch and restart MySQL replication after errors

    Back

    Maintained by: VINCENT KANDASAMY, Database Architect/Administrator (kandasf@hotmail.com)
    Last updated: Aug 17, 17:31