PDF (A4) - 35.2Mb
Man Pages (TGZ) - 256.4Kb
Man Pages (Zip) - 361.2Kb
Info (Gzip) - 3.4Mb
Info (Zip) - 3.4Mb
MySQL Globalization
MySQL Information Schema
MySQL Installation Guide
MySQL and Linux/Unix
MySQL and macOS
MySQL Partitioning
MySQL Performance Schema
MySQL Replication
Using the MySQL Yum Repository
MySQL Restrictions and Limitations
Security in MySQL
MySQL and Solaris
Building MySQL from Source
Starting and Stopping MySQL
MySQL Tutorial
MySQL and Windows
MySQL NDB Cluster 7.5
This section describes problems that can occur when using the 2-digitYEAR(2) data type and provides information about converting existingYEAR(2) columns to 4-digit year-valued columns, which can be declared asYEAR with an implicit display width of 4 characters, or equivalently asYEAR(4) with an explicit display width.
Although the internal range of values forYEAR/YEAR(4) and the deprecatedYEAR(2) type is the same (1901 to2155, and0000), the display width forYEAR(2) makes that type inherently ambiguous because displayed values indicate only the last two digits of the internal values and omit the century digits. The result can be a loss of information under certain circumstances. For this reason, avoid usingYEAR(2) in your applications and useYEAR/YEAR(4) wherever you need a year-valued data type. As of MySQL 5.7.5, support forYEAR(2) is removed and existing 2-digitYEAR(2) columns must be converted to 4-digitYEAR columns to become usable again.
Issues with theYEAR(2) data type include ambiguity of displayed values, and possible loss of information when values are dumped and reloaded or converted to strings.
Displayed
YEAR(2)values can be ambiguous. It is possible for up to threeYEAR(2)values that have different internal values to have the same displayed value, as the following example demonstrates:mysql> CREATE TABLE t (y2 YEAR(2), y4 YEAR);Query OK, 0 rows affected, 1 warning (0.01 sec)mysql> INSERT INTO t (y2) VALUES(1912),(2012),(2112);Query OK, 3 rows affected (0.00 sec)Records: 3 Duplicates: 0 Warnings: 0mysql> UPDATE t SET y4 = y2;Query OK, 3 rows affected (0.00 sec)Rows matched: 3 Changed: 3 Warnings: 0mysql> SELECT * FROM t;+------+------+| y2 | y4 |+------+------+| 12 | 1912 || 12 | 2012 || 12 | 2112 |+------+------+3 rows in set (0.00 sec)If you usemysqldump to dump the table created in the preceding example, the dump file represents all
y2values using the same 2-digit representation (12). If you reload the table from the dump file, all resulting rows have internal value2012and display value12, thus losing the distinctions between them.Conversion of a 2-digit or 4-digit
YEARdata value to string form uses the data type display width. Suppose that aYEAR(2)column and aYEAR/YEAR(4)column both contain the value1970. Assigning each column to a string results in a value of'70'or'1970', respectively. That is, loss of information occurs for conversion fromYEAR(2)to string.Values outside the range from
1970to2069are stored incorrectly when inserted into aYEAR(2)column in aCSVtable. For example, inserting2211results in a display value of11but an internal value of2011.
To avoid these problems, use the 4-digitYEAR orYEAR(4) data type rather than the 2-digitYEAR(2) data type. Suggestions regarding migration strategies appear later in this section.
Before MySQL 5.7.5, support forYEAR(2) is diminished. As of MySQL 5.7.5, support forYEAR(2) is removed.
YEAR(2)column definitions for new tables produce warnings or errors:Before MySQL 5.7.5,
YEAR(2)column definitions for new tables are converted (with anER_INVALID_YEAR_COLUMN_LENGTHwarning) to 4-digitYEARcolumns:mysql> CREATE TABLE t1 (y YEAR(2));Query OK, 0 rows affected, 1 warning (0.04 sec)mysql> SHOW WARNINGS\G*************************** 1. row *************************** Level: Warning Code: 1818Message: YEAR(2) column type is deprecated. Creating YEAR(4) column instead.1 row in set (0.00 sec)mysql> SHOW CREATE TABLE t1\G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `y` year(4) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.00 sec)As of MySQL 5.7.5,
YEAR(2)column definitions for new tables produce anER_INVALID_YEAR_COLUMN_LENGTHerror:mysql> CREATE TABLE t1 (y YEAR(2));ERROR 1818 (HY000): Supports only YEAR or YEAR(4) column.
Several programs or statements convert
YEAR(2)columns to 4-digitYEARcolumns automatically:ALTER TABLEstatements that result in a table rebuild.REPAIR TABLE(whichCHECK TABLErecommends you use, if it finds a table that containsYEAR(2)columns).mysql_upgrade (which uses
REPAIR TABLE).Dumping withmysqldump and reloading the dump file. Unlike the conversions performed by the preceding three items, a dump and reload has the potential to change data values.
A MySQL upgrade usually involves at least one of the last two items. However, with respect to
YEAR(2),mysql_upgrade is preferable tomysqldump, which, as noted, can change data values.
To convert 2-digitYEAR(2) columns to 4-digitYEAR columns, you can do so manually at any time without upgrading. Alternatively, you can upgrade to a version of MySQL with reduced or removed support forYEAR(2) (MySQL 5.6.6 or later), then have MySQL convertYEAR(2) columns automatically. In the latter case, avoid upgrading by dumping and reloading your data because that can change data values. In addition, if you use replication, there are upgrade considerations you must take into account.
To convert 2-digitYEAR(2) columns to 4-digitYEAR manually, useALTER TABLE orREPAIR TABLE. Suppose that a tablet1 has this definition:
CREATE TABLE t1 (ycol YEAR(2) NOT NULL DEFAULT '70'); Modify the column usingALTER TABLE as follows:
ALTER TABLE t1 FORCE; TheALTER TABLE statement converts the table without changingYEAR(2) values. If the server is a replication source, theALTER TABLE statement replicates to replicas and makes the corresponding table change on each one.
Another migration method is to perform a binary upgrade: Upgrade MySQL in place without dumping and reloading your data. Then runmysql_upgrade, which usesREPAIR TABLE to convert 2-digitYEAR(2) columns to 4-digitYEAR columns without changing data values. If the server is a replication source, theREPAIR TABLE statements replicate to replicas and make the corresponding table changes on each one, unless you invokemysql_upgrade with the--skip-write-binlog option.
Upgrades to replication servers usually involve upgrading replicas to a newer version of MySQL, then upgrading the source. For example, if a source and replica both run MySQL 5.5, a typical upgrade sequence involves upgrading the replica to 5.6, then upgrading the source to 5.6. With regard to the different treatment ofYEAR(2) as of MySQL 5.6.6, that upgrade sequence results in a problem: Suppose that the replica has been upgraded but not yet the source. Then creating a table containing a 2-digitYEAR(2) column on the source results in a table containing a 4-digitYEAR column on the replica. Consequently, the following operations have a different result on the source and replica, if you use statement-based replication:
To avoid such problems, modify all 2-digitYEAR(2) columns on the source to 4-digitYEAR columns before upgrading. (UseALTER TABLE, as described previously.) That makes it possible to upgrade normally (replica first, then source) without introducing anyYEAR(2) toYEAR(4) differences between the source and replica.
One migration method should be avoided: Do not dump your data withmysqldump and reload the dump file after upgrading. That has the potential to changeYEAR(2) values, as described previously.
A migration from 2-digitYEAR(2) columns to 4-digitYEAR columns should also involve examining application code for the possibility of changed behavior under conditions such as these:
PDF (A4) - 35.2Mb
Man Pages (TGZ) - 256.4Kb
Man Pages (Zip) - 361.2Kb
Info (Gzip) - 3.4Mb
Info (Zip) - 3.4Mb
MySQL Globalization
MySQL Information Schema
MySQL Installation Guide
MySQL and Linux/Unix
MySQL and macOS
MySQL Partitioning
MySQL Performance Schema
MySQL Replication
Using the MySQL Yum Repository
MySQL Restrictions and Limitations
Security in MySQL
MySQL and Solaris
Building MySQL from Source
Starting and Stopping MySQL
MySQL Tutorial
MySQL and Windows
MySQL NDB Cluster 7.5