WL#5989: Support InnoDB tablespace version in se_private_data of mysql.tablespaces

Affects: Server-8.0   —   Status: Complete   —   Priority: Medium

It is necessary to create a durable InnoDB version ID so to mark new InnoDB
releases with any new features have upgrade/downgrade impact/requirement.

The Server Version ID is different with InnoDB file format, which is used to
identify new on disk data storage format. The Server Version ID is a more
generic ID, identifying a release with new features.

Current idea is that such Server Version ID is a 4 byte unsigned integer with
identical value of "MYSQL_VERSION_ID" defined in mysql_version.h.  The 
MYSQL_VERSION_ID is a numeric value with patch number is lower 2 digit, give it
0-99 possible value, and minor number is next 2 digit, also with possible of 0
to 99 value. And we can compose a "major.minor.patch" string if necessary to
display (as in I_S table), but also easy to compare.

Such server version is stored as "SERVER_VERSION" field in mysql.tablespaces'
se_private_data for InnoDB engine as part of Tablespace Metadata. It is also
stamped on the page 0 of the tablespace, at byte 8 to 12. So even if a
tablepsace is moved, the version info can still be easily identified.

Since the version ID is automatically picked up from server define, there is no
need to manually update the number for each release.

In addition to Server Verson ID, we also store the tablespace version as
"SPACE_VERSION" in mysql.tablespace's se_private_data. It is persisted on the
page 0 of the tablespace from byte 12 to 16. The tablespace version is used
specifically identify any space format changes in the tablespace, no matter it
would be a new tablespace header or new page format etc.
1. The server version field is properly set in mysql.tablespsaces'
se_private_data "server_version" field. The proper version for this 8.0 release
is "8.0.4", the MYSQL_VERSION_ID is 80004, and if merged to 9.0, the value will
be 90000.

2. The tablespace version field is properly set in in mysql.tablespsaces'
se_private_data "space_version" field. 

3. The server version field is stamped on the page 0 of tablespace, at byte 8

4. The space version field is stamped on the page 0 of tablesapce, at byte 12

5.. The information_schema.innodb_tablespaces will display the server version
properly in "8.0.4" string in mysql-8.0 or "9.0.0" in mysql-trunk

6. The information_schema.innodb_tablespaces will display the tablespace version
properly as value 1.

7. When 5.7 database is upgraded to 8.0 server, the proper version should be put
on the tablespace se_private_data

8. For upgrade with tablespace page 0 stamp (from 5.7), the work will be done by
WL#11063: Update server version information in InnoDB tablespaces 
The server version for a tablespace is more or less a "birth marker" or
"certified marker" for a tablespace, specifying when this tablespace is created,
or last major upgraded. For the normal DDL/DML operation, and even minor upgrade
(from 8.0.8 to 8.0.9 etc.) it should never be changed.

This could server as a "gate keeper" to know if certain operations (such as
import tablespace) can be performed on a tablespace on hand, or the tablespace
is too "old", and requires other upgrade actions before be able to "imported".

As mentioned, we will need only a single se_private_field to store all 3
versions, it is identical to MYSQL_VERSION_ID defined in server.

Currently, for 9.0.0, that server version values comes to 90000. The tablespace
version starts with 1:

mysql> select name, se_private_data from mysql.tablespaces;
| name             | se_private_data                                           
| mysql            |
flags=2048;id=4294967294;server_version=90000;space_version=1; |
| innodb_system    | flags=2048;id=0;server_version=90000;space_version=1;     
| innodb_temporary |
flags=4096;id=4294967293;server_version=90000;space_version=1; |
| innodb_undo_001  | flags=0;id=4294967279;server_version=90000;space_version=1;
| innodb_undo_002  | flags=0;id=4294967278;server_version=90000;space_version=1;
| sys/sys_config   | flags=16417;id=1;server_version=90000;space_version=1;    
6 rows in set (0.01 sec)

But it will be properly interpreted in INFORMATION_SCHEMA.INNODB_TABLESPACES:

mysql>  SELECT name, server_version, space_version FROM information_schema.inno
| name             | space_server_version | space_version |
| mysql            | 9.0.0                |             1 |
| innodb_temporary | 9.0.0                |             1 |
| innodb_undo_001  | 9.0.0                |             1 |
| innodb_undo_002  | 9.0.0                |             1 |
| sys/sys_config   | 9.0.0                |             1 |
5 rows in set (0.00 sec)

Since the versions come from MYSQL_VERSION_*, so it always fits actual server
The tablespace version is defined as following:

/** Server version that the tablespace created */

/** The tablespace version that the tablespace created */

The bit is set to tablespace in follow scenario:

1. During bootstrap, the DD_SPACE_CURRENT_VERSION is also built into "mysql" and
"innodb_system" tablespace in innobase_init_files()

2. For other tablespaces, the DD_SPACE_CURRENT_VERSION is set to dd::Tabelspace
in dd_write_tablespace() and create_dd_tablespace().

3. During upgrade, the DD_SPACE_CURRENT_VERSION is set to each 5.7 tablespace
with dd_upgrade_tablespace()

4. For INFORMATION_SCHEMA.INNODB_TABLESPACES, version field will be re-assembled
into "8.0.4" string in i_s_dict_fill_innodb_tablespaces()