vitess.io/vitess@v0.16.2/go/vt/vttablet/onlineddl/schema.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package onlineddl
    18  
    19  const (
    20  	sqlInsertMigration = `INSERT IGNORE INTO _vt.schema_migrations (
    21  		migration_uuid,
    22  		keyspace,
    23  		shard,
    24  		mysql_schema,
    25  		mysql_table,
    26  		migration_statement,
    27  		strategy,
    28  		options,
    29  		ddl_action,
    30  		requested_timestamp,
    31  		migration_context,
    32  		migration_status,
    33  		tablet,
    34  		retain_artifacts_seconds,
    35  		postpone_launch,
    36  		postpone_completion,
    37  		allow_concurrent,
    38  		reverted_uuid,
    39  		is_view
    40  	) VALUES (
    41  		%a, %a, %a, %a, %a, %a, %a, %a, %a, NOW(6), %a, %a, %a, %a, %a, %a, %a, %a, %a
    42  	)`
    43  
    44  	sqlSelectQueuedMigrations = `SELECT
    45  			migration_uuid,
    46  			ddl_action,
    47  			is_view,
    48  			is_immediate_operation,
    49  			postpone_launch,
    50  			postpone_completion,
    51  			ready_to_complete
    52  		FROM _vt.schema_migrations
    53  		WHERE
    54  			migration_status='queued'
    55  			AND reviewed_timestamp IS NOT NULL
    56  		ORDER BY id
    57  	`
    58  	sqlUpdateMySQLTable = `UPDATE _vt.schema_migrations
    59  			SET mysql_table=%a
    60  		WHERE
    61  			migration_uuid=%a
    62  	`
    63  	sqlUpdateMigrationStatus = `UPDATE _vt.schema_migrations
    64  			SET migration_status=%a
    65  		WHERE
    66  			migration_uuid=%a
    67  	`
    68  	sqlUpdateMigrationStatusFailedOrCancelled = `UPDATE _vt.schema_migrations
    69  			SET migration_status=IF(cancelled_timestamp IS NULL, 'failed', 'cancelled')
    70  		WHERE
    71  			migration_uuid=%a
    72  	`
    73  	sqlUpdateMigrationProgress = `UPDATE _vt.schema_migrations
    74  			SET progress=%a
    75  		WHERE
    76  			migration_uuid=%a
    77  	`
    78  	sqlUpdateMigrationETASeconds = `UPDATE _vt.schema_migrations
    79  			SET eta_seconds=%a
    80  		WHERE
    81  			migration_uuid=%a
    82  	`
    83  	sqlUpdateMigrationRowsCopied = `UPDATE _vt.schema_migrations
    84  			SET rows_copied=%a
    85  		WHERE
    86  			migration_uuid=%a
    87  	`
    88  	sqlUpdateMigrationIsView = `UPDATE _vt.schema_migrations
    89  			SET is_view=%a
    90  		WHERE
    91  			migration_uuid=%a
    92  	`
    93  	sqlUpdateMigrationSetImmediateOperation = `UPDATE _vt.schema_migrations
    94  			SET is_immediate_operation=1
    95  		WHERE
    96  			migration_uuid=%a
    97  	`
    98  	sqlUpdateMigrationReadyToComplete = `UPDATE _vt.schema_migrations
    99  			SET ready_to_complete=%a
   100  		WHERE
   101  			migration_uuid=%a
   102  	`
   103  	sqlUpdateMigrationStowawayTable = `UPDATE _vt.schema_migrations
   104  			SET stowaway_table=%a
   105  		WHERE
   106  			migration_uuid=%a
   107  	`
   108  	sqlUpdateMigrationUserThrottleRatio = `UPDATE _vt.schema_migrations
   109  			SET user_throttle_ratio=%a
   110  		WHERE
   111  			migration_uuid=%a
   112  	`
   113  	sqlUpdateMigrationStartedTimestamp = `UPDATE _vt.schema_migrations SET
   114  			started_timestamp =IFNULL(started_timestamp,  NOW(6)),
   115  			liveness_timestamp=IFNULL(liveness_timestamp, NOW(6))
   116  		WHERE
   117  			migration_uuid=%a
   118  	`
   119  	sqlUpdateMigrationTimestamp = `UPDATE _vt.schema_migrations
   120  			SET %s=NOW(6)
   121  		WHERE
   122  			migration_uuid=%a
   123  	`
   124  	sqlUpdateMigrationVitessLivenessIndicator = `UPDATE _vt.schema_migrations
   125  			SET vitess_liveness_indicator=%a
   126  		WHERE
   127  			migration_uuid=%a
   128  	`
   129  	sqlUpdateMigrationLogPath = `UPDATE _vt.schema_migrations
   130  			SET log_path=%a, log_file=%a
   131  		WHERE
   132  			migration_uuid=%a
   133  	`
   134  	sqlUpdateArtifacts = `UPDATE _vt.schema_migrations
   135  			SET artifacts=concat(%a, ',', artifacts), cleanup_timestamp=NULL
   136  		WHERE
   137  			migration_uuid=%a
   138  	`
   139  	sqlClearArtifacts = `UPDATE _vt.schema_migrations
   140  			SET artifacts=''
   141  		WHERE
   142  			migration_uuid=%a
   143  	`
   144  	sqlUpdateSpecialPlan = `UPDATE _vt.schema_migrations
   145  			SET special_plan=%a
   146  		WHERE
   147  			migration_uuid=%a
   148  	`
   149  	sqlUpdateStage = `UPDATE _vt.schema_migrations
   150  			SET stage=%a
   151  		WHERE
   152  			migration_uuid=%a
   153  	`
   154  	sqlIncrementCutoverAttempts = `UPDATE _vt.schema_migrations
   155  			SET cutover_attempts=cutover_attempts+1
   156  		WHERE
   157  			migration_uuid=%a
   158  	`
   159  	sqlUpdateReadyForCleanup = `UPDATE _vt.schema_migrations
   160  			SET retain_artifacts_seconds=-1
   161  		WHERE
   162  			migration_uuid=%a
   163  	`
   164  	sqlUpdateLaunchMigration = `UPDATE _vt.schema_migrations
   165  			SET postpone_launch=0
   166  		WHERE
   167  			migration_uuid=%a
   168  			AND postpone_launch != 0
   169  	`
   170  	sqlUpdateCompleteMigration = `UPDATE _vt.schema_migrations
   171  			SET postpone_completion=0
   172  		WHERE
   173  			migration_uuid=%a
   174  			AND postpone_completion != 0
   175  	`
   176  	sqlUpdateTablet = `UPDATE _vt.schema_migrations
   177  			SET tablet=%a
   178  		WHERE
   179  			migration_uuid=%a
   180  	`
   181  	sqlUpdateTabletFailure = `UPDATE _vt.schema_migrations
   182  			SET tablet_failure=1
   183  		WHERE
   184  			migration_uuid=%a
   185  	`
   186  	sqlUpdateDDLAction = `UPDATE _vt.schema_migrations
   187  			SET ddl_action=%a
   188  		WHERE
   189  			migration_uuid=%a
   190  	`
   191  	sqlUpdateMessage = `UPDATE _vt.schema_migrations
   192  			SET message=%a
   193  		WHERE
   194  			migration_uuid=%a
   195  	`
   196  	sqlUpdateSchemaAnalysis = `UPDATE _vt.schema_migrations
   197  			SET added_unique_keys=%a, removed_unique_keys=%a, removed_unique_key_names=%a,
   198  			dropped_no_default_column_names=%a, expanded_column_names=%a,
   199  			revertible_notes=%a
   200  		WHERE
   201  			migration_uuid=%a
   202  	`
   203  	sqlUpdateMigrationTableRows = `UPDATE _vt.schema_migrations
   204  			SET table_rows=%a
   205  		WHERE
   206  			migration_uuid=%a
   207  	`
   208  	sqlUpdateMigrationProgressByRowsCopied = `UPDATE _vt.schema_migrations
   209  			SET
   210  				progress=CASE
   211  					WHEN table_rows=0 THEN 100
   212  					ELSE LEAST(100, 100*%a/table_rows)
   213  				END
   214  		WHERE
   215  			migration_uuid=%a
   216  	`
   217  	sqlUpdateMigrationETASecondsByProgress = `UPDATE _vt.schema_migrations
   218  			SET
   219  				eta_seconds=CASE
   220  					WHEN progress=0 THEN -1
   221  					WHEN table_rows=0 THEN 0
   222  					ELSE GREATEST(0,
   223  						TIMESTAMPDIFF(SECOND, started_timestamp, NOW())*((100/progress)-1)
   224  					)
   225  				END
   226  		WHERE
   227  			migration_uuid=%a
   228  	`
   229  	sqlUpdateLastThrottled = `UPDATE _vt.schema_migrations
   230  			SET last_throttled_timestamp=FROM_UNIXTIME(%a), component_throttled=%a
   231  		WHERE
   232  			migration_uuid=%a
   233  	`
   234  	sqlRetryMigrationWhere = `UPDATE _vt.schema_migrations
   235  		SET
   236  			migration_status='queued',
   237  			tablet=%a,
   238  			retries=retries + 1,
   239  			tablet_failure=0,
   240  			message='',
   241  			stage='',
   242  			cutover_attempts=0,
   243  			ready_timestamp=NULL,
   244  			started_timestamp=NULL,
   245  			liveness_timestamp=NULL,
   246  			cancelled_timestamp=NULL,
   247  			completed_timestamp=NULL,
   248  			cleanup_timestamp=NULL
   249  		WHERE
   250  			migration_status IN ('failed', 'cancelled')
   251  			AND (%s)
   252  			LIMIT 1
   253  	`
   254  	sqlRetryMigration = `UPDATE _vt.schema_migrations
   255  		SET
   256  			migration_status='queued',
   257  			tablet=%a,
   258  			retries=retries + 1,
   259  			tablet_failure=0,
   260  			message='',
   261  			stage='',
   262  			cutover_attempts=0,
   263  			ready_timestamp=NULL,
   264  			started_timestamp=NULL,
   265  			liveness_timestamp=NULL,
   266  			cancelled_timestamp=NULL,
   267  			completed_timestamp=NULL,
   268  			cleanup_timestamp=NULL
   269  		WHERE
   270  			migration_status IN ('failed', 'cancelled')
   271  			AND migration_uuid=%a
   272  	`
   273  	sqlWhereTabletFailure = `
   274  		tablet_failure=1
   275  		AND migration_status='failed'
   276  		AND retries=0
   277  	`
   278  	sqlSelectRunningMigrations = `SELECT
   279  			migration_uuid,
   280  			postpone_completion,
   281  			stowaway_table,
   282  			timestampdiff(second, started_timestamp, now()) as elapsed_seconds
   283  		FROM _vt.schema_migrations
   284  		WHERE
   285  			migration_status='running'
   286  	`
   287  	sqlSelectCompleteMigrationsOnTable = `SELECT
   288  			migration_uuid,
   289  			strategy
   290  		FROM _vt.schema_migrations
   291  		WHERE
   292  			migration_status='complete'
   293  			AND keyspace=%a
   294  			AND mysql_table=%a
   295  		ORDER BY
   296  			completed_timestamp DESC
   297  		LIMIT 1
   298  	`
   299  	sqlSelectCompleteMigrationsByContextAndSQL = `SELECT
   300  			migration_uuid,
   301  			strategy
   302  		FROM _vt.schema_migrations
   303  		WHERE
   304  			migration_status='complete'
   305  			AND keyspace=%a
   306  			AND migration_context=%a
   307  			AND migration_statement=%a
   308  		LIMIT 1
   309  	`
   310  	sqlSelectStaleMigrations = `SELECT
   311  			migration_uuid
   312  		FROM _vt.schema_migrations
   313  		WHERE
   314  			migration_status='running'
   315  			AND liveness_timestamp < NOW() - INTERVAL %a MINUTE
   316  	`
   317  	sqlSelectPendingMigrations = `SELECT
   318  			migration_uuid,
   319  			keyspace,
   320  			mysql_table,
   321  			migration_status
   322  		FROM _vt.schema_migrations
   323  		WHERE
   324  			migration_status IN ('queued', 'ready', 'running')
   325  		ORDER BY id
   326  	`
   327  	sqlSelectQueuedUnreviewedMigrations = `SELECT
   328  			migration_uuid
   329  		FROM _vt.schema_migrations
   330  		WHERE
   331  			migration_status='queued'
   332  			AND reviewed_timestamp IS NULL
   333  		ORDER BY id
   334  	`
   335  	sqlSelectUncollectedArtifacts = `SELECT
   336  			migration_uuid,
   337  			artifacts,
   338  			log_path
   339  		FROM _vt.schema_migrations
   340  		WHERE
   341  			migration_status IN ('complete', 'failed')
   342  			AND cleanup_timestamp IS NULL
   343  			AND completed_timestamp <= IF(retain_artifacts_seconds=0,
   344  				NOW() - INTERVAL %a SECOND,
   345  				NOW() - INTERVAL retain_artifacts_seconds SECOND
   346  			)
   347  	`
   348  	sqlFixCompletedTimestamp = `UPDATE _vt.schema_migrations
   349  		SET
   350  			completed_timestamp=NOW(6)
   351  		WHERE
   352  			migration_status='failed'
   353  			AND cleanup_timestamp IS NULL
   354  			AND completed_timestamp IS NULL
   355  	`
   356  	sqlSelectMigration = `SELECT
   357  			id,
   358  			migration_uuid,
   359  			keyspace,
   360  			shard,
   361  			mysql_schema,
   362  			mysql_table,
   363  			migration_statement,
   364  			strategy,
   365  			options,
   366  			added_timestamp,
   367  			ready_timestamp,
   368  			started_timestamp,
   369  			liveness_timestamp,
   370  			completed_timestamp,
   371  			migration_status,
   372  			log_path,
   373  			log_file,
   374  			retries,
   375  			ddl_action,
   376  			artifacts,
   377  			tablet,
   378  			added_unique_keys,
   379  			removed_unique_keys,
   380  			migration_context,
   381  			retain_artifacts_seconds,
   382  			is_view,
   383  			ready_to_complete,
   384  			reverted_uuid,
   385  			stowaway_table,
   386  			rows_copied,
   387  			vitess_liveness_indicator,
   388  			user_throttle_ratio,
   389  			last_throttled_timestamp,
   390  			cancelled_timestamp,
   391  			component_throttled,
   392  			postpone_launch,
   393  			postpone_completion,
   394  			is_immediate_operation,
   395  			reviewed_timestamp
   396  		FROM _vt.schema_migrations
   397  		WHERE
   398  			migration_uuid=%a
   399  	`
   400  	sqlSelectReadyMigrations = `SELECT
   401  			migration_uuid
   402  		FROM _vt.schema_migrations
   403  		WHERE
   404  			migration_status='ready'
   405  		ORDER BY id
   406  	`
   407  	sqlSelectPTOSCMigrationTriggers = `SELECT
   408  			TRIGGER_SCHEMA as trigger_schema,
   409  			TRIGGER_NAME as trigger_name
   410  		FROM INFORMATION_SCHEMA.TRIGGERS
   411  		WHERE
   412  			EVENT_OBJECT_SCHEMA=%a
   413  			AND EVENT_OBJECT_TABLE=%a
   414  			AND ACTION_TIMING='AFTER'
   415  			AND LEFT(TRIGGER_NAME, 7)='pt_osc_'
   416  		`
   417  	sqlSelectColumnTypes = `
   418  		select
   419  				*,
   420  				COLUMN_DEFAULT IS NULL AS is_default_null
   421  			from
   422  				information_schema.columns
   423  			where
   424  				table_schema=%a
   425  				and table_name=%a
   426  		`
   427  	selSelectCountFKParentConstraints = `
   428  		SELECT
   429  			COUNT(*) as num_fk_constraints
   430  		FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
   431  		WHERE
   432  			REFERENCED_TABLE_SCHEMA=%a AND REFERENCED_TABLE_NAME=%a
   433  			AND REFERENCED_TABLE_NAME IS NOT NULL
   434  		`
   435  	selSelectCountFKChildConstraints = `
   436  		SELECT
   437  			COUNT(*) as num_fk_constraints
   438  		FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
   439  		WHERE
   440  			TABLE_SCHEMA=%a AND TABLE_NAME=%a
   441  			AND REFERENCED_TABLE_NAME IS NOT NULL
   442  		`
   443  	sqlSelectUniqueKeys = `
   444  	SELECT
   445  		COLUMNS.TABLE_SCHEMA as table_schema,
   446  		COLUMNS.TABLE_NAME as table_name,
   447  		COLUMNS.COLUMN_NAME as column_name,
   448  		UNIQUES.INDEX_NAME as index_name,
   449  		UNIQUES.COLUMN_NAMES as column_names,
   450  		UNIQUES.COUNT_COLUMN_IN_INDEX as count_column_in_index,
   451  		COLUMNS.DATA_TYPE as data_type,
   452  		COLUMNS.CHARACTER_SET_NAME as character_set_name,
   453  		LOCATE('auto_increment', EXTRA) > 0 as is_auto_increment,
   454  		(DATA_TYPE='float' OR DATA_TYPE='double') AS is_float,
   455  		has_nullable
   456  	FROM INFORMATION_SCHEMA.COLUMNS INNER JOIN (
   457  		SELECT
   458  			TABLE_SCHEMA,
   459  			TABLE_NAME,
   460  			INDEX_NAME,
   461  			COUNT(*) AS COUNT_COLUMN_IN_INDEX,
   462  			GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC) AS COLUMN_NAMES,
   463  			SUBSTRING_INDEX(GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX ASC), ',', 1) AS FIRST_COLUMN_NAME,
   464  			SUM(NULLABLE='YES') > 0 AS has_nullable
   465  		FROM INFORMATION_SCHEMA.STATISTICS
   466  		WHERE
   467  			NON_UNIQUE=0
   468  			AND TABLE_SCHEMA=%a
   469  			AND TABLE_NAME=%a
   470  		GROUP BY TABLE_SCHEMA, TABLE_NAME, INDEX_NAME
   471  	) AS UNIQUES
   472  	ON (
   473  		COLUMNS.COLUMN_NAME = UNIQUES.FIRST_COLUMN_NAME
   474  	)
   475  	WHERE
   476  		COLUMNS.TABLE_SCHEMA=%a
   477  		AND COLUMNS.TABLE_NAME=%a
   478  	ORDER BY
   479  		COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME,
   480  		CASE UNIQUES.INDEX_NAME
   481  			WHEN 'PRIMARY' THEN 0
   482  			ELSE 1
   483  		END,
   484  		CASE has_nullable
   485  			WHEN 0 THEN 0
   486  			ELSE 1
   487  		END,
   488  		CASE IFNULL(CHARACTER_SET_NAME, '')
   489  				WHEN '' THEN 0
   490  				ELSE 1
   491  		END,
   492  		CASE DATA_TYPE
   493  			WHEN 'tinyint' THEN 0
   494  			WHEN 'smallint' THEN 1
   495  			WHEN 'int' THEN 2
   496  			WHEN 'bigint' THEN 3
   497  			ELSE 100
   498  		END,
   499  		COUNT_COLUMN_IN_INDEX
   500  	`
   501  	sqlDropTrigger      = "DROP TRIGGER IF EXISTS `%a`.`%a`"
   502  	sqlShowTablesLike   = "SHOW TABLES LIKE '%a'"
   503  	sqlDropTable        = "DROP TABLE `%a`"
   504  	sqlShowColumnsFrom  = "SHOW COLUMNS FROM `%a`"
   505  	sqlShowTableStatus  = "SHOW TABLE STATUS LIKE '%a'"
   506  	sqlShowCreateTable  = "SHOW CREATE TABLE `%a`"
   507  	sqlGetAutoIncrement = `
   508  		SELECT
   509  			AUTO_INCREMENT
   510  		FROM INFORMATION_SCHEMA.TABLES
   511  		WHERE
   512  			TABLES.TABLE_SCHEMA=%a
   513  			AND TABLES.TABLE_NAME=%a
   514  			AND AUTO_INCREMENT IS NOT NULL
   515  		`
   516  	sqlAlterTableAutoIncrement      = "ALTER TABLE `%s` AUTO_INCREMENT=%a"
   517  	sqlAlterTableExchangePartition  = "ALTER TABLE `%a` EXCHANGE PARTITION `%a` WITH TABLE `%a`"
   518  	sqlAlterTableRemovePartitioning = "ALTER TABLE `%a` REMOVE PARTITIONING"
   519  	sqlAlterTableDropPartition      = "ALTER TABLE `%a` DROP PARTITION `%a`"
   520  	sqlStartVReplStream             = "UPDATE _vt.vreplication set state='Running' where db_name=%a and workflow=%a"
   521  	sqlStopVReplStream              = "UPDATE _vt.vreplication set state='Stopped' where db_name=%a and workflow=%a"
   522  	sqlDeleteVReplStream            = "DELETE FROM _vt.vreplication where db_name=%a and workflow=%a"
   523  	sqlReadVReplStream              = `SELECT
   524  			id,
   525  			workflow,
   526  			source,
   527  			pos,
   528  			time_updated,
   529  			transaction_timestamp,
   530  			time_heartbeat,
   531  			time_throttled,
   532  			component_throttled,
   533  			state,
   534  			message,
   535  			rows_copied
   536  		FROM _vt.vreplication
   537  		WHERE
   538  			workflow=%a
   539  		`
   540  	sqlReadCountCopyState = `SELECT
   541  			count(*) as cnt
   542  		FROM
   543  			_vt.copy_state
   544  		WHERE vrepl_id=%a
   545  		`
   546  	sqlSwapTables         = "RENAME TABLE `%a` TO `%a`, `%a` TO `%a`, `%a` TO `%a`"
   547  	sqlRenameTable        = "RENAME TABLE `%a` TO `%a`"
   548  	sqlLockTwoTablesWrite = "LOCK TABLES `%a` WRITE, `%a` WRITE"
   549  	sqlUnlockTables       = "UNLOCK TABLES"
   550  	sqlCreateSentryTable  = "CREATE TABLE IF NOT EXISTS `%a` (id INT PRIMARY KEY)"
   551  	sqlFindProcess        = "SELECT id, Info as info FROM information_schema.processlist WHERE id=%a AND Info LIKE %a"
   552  )
   553  
   554  const (
   555  	retryMigrationHint     = "retry"
   556  	cancelMigrationHint    = "cancel"
   557  	cancelAllMigrationHint = "cancel-all"
   558  	completeMigrationHint  = "complete"
   559  )
   560  
   561  var (
   562  	sqlCreateOnlineDDLUser = []string{
   563  		`CREATE USER IF NOT EXISTS %s IDENTIFIED BY '%s'`,
   564  		`ALTER USER %s IDENTIFIED BY '%s'`,
   565  	}
   566  	sqlGrantOnlineDDLSuper = []string{
   567  		`GRANT SUPER ON *.* TO %s`,
   568  	}
   569  	sqlGrantOnlineDDLUser = []string{
   570  		`GRANT PROCESS, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO %s`,
   571  		`GRANT ALTER, CREATE, CREATE VIEW, SHOW VIEW, DELETE, DROP, INDEX, INSERT, LOCK TABLES, SELECT, TRIGGER, UPDATE ON *.* TO %s`,
   572  	}
   573  	sqlDropOnlineDDLUser = `DROP USER IF EXISTS %s`
   574  )