github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/meta/meta.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package meta
    15  
    16  import (
    17  	"encoding/binary"
    18  	"encoding/json"
    19  	"fmt"
    20  	"strconv"
    21  	"strings"
    22  	"sync"
    23  	"time"
    24  
    25  	"github.com/insionng/yougam/libraries/juju/errors"
    26  	"github.com/insionng/yougam/libraries/pingcap/tidb/kv"
    27  	"github.com/insionng/yougam/libraries/pingcap/tidb/model"
    28  	"github.com/insionng/yougam/libraries/pingcap/tidb/mysql"
    29  	"github.com/insionng/yougam/libraries/pingcap/tidb/structure"
    30  	"github.com/insionng/yougam/libraries/pingcap/tidb/terror"
    31  )
    32  
    33  var (
    34  	globalIDMutex sync.Mutex
    35  )
    36  
    37  // Meta structure:
    38  //	NextGlobalID -> int64
    39  //	SchemaVersion -> int64
    40  //	DBs -> {
    41  //		DB:1 -> db meta data []byte
    42  //		DB:2 -> db meta data []byte
    43  //	}
    44  //	DB:1 -> {
    45  //		Table:1 -> table meta data []byte
    46  //		Table:2 -> table meta data []byte
    47  //		TID:1 -> int64
    48  //		TID:2 -> int64
    49  //	}
    50  //
    51  
    52  var (
    53  	mNextGlobalIDKey  = []byte("NextGlobalID")
    54  	mSchemaVersionKey = []byte("SchemaVersionKey")
    55  	mDBs              = []byte("DBs")
    56  	mDBPrefix         = "DB"
    57  	mTablePrefix      = "Table"
    58  	mTableIDPrefix    = "TID"
    59  	mBootstrapKey     = []byte("BootstrapKey")
    60  )
    61  
    62  var (
    63  	errInvalidTableKey = terror.ClassMeta.New(codeInvalidTableKey, "invalid table meta key")
    64  	errInvalidDBKey    = terror.ClassMeta.New(codeInvalidDBKey, "invalid db key")
    65  
    66  	// ErrDBExists is the error for db exists.
    67  	ErrDBExists = terror.ClassMeta.New(codeDatabaseExists, "database already exists")
    68  	// ErrDBNotExists is the error for db not exists.
    69  	ErrDBNotExists = terror.ClassMeta.New(codeDatabaseNotExists, "database doesn't exist")
    70  	// ErrTableExists is the error for table exists.
    71  	ErrTableExists = terror.ClassMeta.New(codeTableExists, "table already exists")
    72  	// ErrTableNotExists is the error for table not exists.
    73  	ErrTableNotExists = terror.ClassMeta.New(codeTableNotExists, "table doesn't exist")
    74  )
    75  
    76  // Meta is for handling meta information in a transaction.
    77  type Meta struct {
    78  	txn *structure.TxStructure
    79  }
    80  
    81  // NewMeta creates a Meta in transaction txn.
    82  func NewMeta(txn kv.Transaction) *Meta {
    83  	t := structure.NewStructure(txn, []byte{'m'})
    84  	return &Meta{txn: t}
    85  }
    86  
    87  // GenGlobalID generates next id globally.
    88  func (m *Meta) GenGlobalID() (int64, error) {
    89  	globalIDMutex.Lock()
    90  	defer globalIDMutex.Unlock()
    91  
    92  	return m.txn.Inc(mNextGlobalIDKey, 1)
    93  }
    94  
    95  // GetGlobalID gets current global id.
    96  func (m *Meta) GetGlobalID() (int64, error) {
    97  	return m.txn.GetInt64(mNextGlobalIDKey)
    98  }
    99  
   100  func (m *Meta) dbKey(dbID int64) []byte {
   101  	return []byte(fmt.Sprintf("%s:%d", mDBPrefix, dbID))
   102  }
   103  
   104  func (m *Meta) parseDatabaseID(key string) (int64, error) {
   105  	seps := strings.Split(key, ":")
   106  	if len(seps) != 2 {
   107  		return 0, errors.Errorf("invalid db key %s", key)
   108  	}
   109  
   110  	n, err := strconv.ParseInt(seps[1], 10, 64)
   111  	return n, errors.Trace(err)
   112  }
   113  
   114  func (m *Meta) autoTalbeIDKey(tableID int64) []byte {
   115  	return []byte(fmt.Sprintf("%s:%d", mTableIDPrefix, tableID))
   116  }
   117  
   118  func (m *Meta) tableKey(tableID int64) []byte {
   119  	return []byte(fmt.Sprintf("%s:%d", mTablePrefix, tableID))
   120  }
   121  
   122  func (m *Meta) parseTableID(key string) (int64, error) {
   123  	seps := strings.Split(key, ":")
   124  	if len(seps) != 2 {
   125  		return 0, errors.Errorf("invalid table meta key %s", key)
   126  	}
   127  
   128  	n, err := strconv.ParseInt(seps[1], 10, 64)
   129  	return n, errors.Trace(err)
   130  }
   131  
   132  // GenAutoTableID adds step to the auto id of the table and returns the sum.
   133  func (m *Meta) GenAutoTableID(dbID int64, tableID int64, step int64) (int64, error) {
   134  	// Check if db exists.
   135  	dbKey := m.dbKey(dbID)
   136  	if err := m.checkDBExists(dbKey); err != nil {
   137  		return 0, errors.Trace(err)
   138  	}
   139  
   140  	// Check if table exists.
   141  	tableKey := m.tableKey(tableID)
   142  	if err := m.checkTableExists(dbKey, tableKey); err != nil {
   143  		return 0, errors.Trace(err)
   144  	}
   145  
   146  	return m.txn.HInc(dbKey, m.autoTalbeIDKey(tableID), step)
   147  }
   148  
   149  // GetAutoTableID gets current auto id with table id.
   150  func (m *Meta) GetAutoTableID(dbID int64, tableID int64) (int64, error) {
   151  	return m.txn.HGetInt64(m.dbKey(dbID), m.autoTalbeIDKey(tableID))
   152  }
   153  
   154  // GetSchemaVersion gets current global schema version.
   155  func (m *Meta) GetSchemaVersion() (int64, error) {
   156  	return m.txn.GetInt64(mSchemaVersionKey)
   157  }
   158  
   159  // GenSchemaVersion generates next schema version.
   160  func (m *Meta) GenSchemaVersion() (int64, error) {
   161  	return m.txn.Inc(mSchemaVersionKey, 1)
   162  }
   163  
   164  func (m *Meta) checkDBExists(dbKey []byte) error {
   165  	v, err := m.txn.HGet(mDBs, dbKey)
   166  	if err != nil {
   167  		return errors.Trace(err)
   168  	} else if v == nil {
   169  		return ErrDBNotExists
   170  	}
   171  
   172  	return nil
   173  }
   174  
   175  func (m *Meta) checkDBNotExists(dbKey []byte) error {
   176  	v, err := m.txn.HGet(mDBs, dbKey)
   177  	if err != nil {
   178  		return errors.Trace(err)
   179  	}
   180  
   181  	if v != nil {
   182  		return ErrDBExists
   183  	}
   184  
   185  	return nil
   186  }
   187  
   188  func (m *Meta) checkTableExists(dbKey []byte, tableKey []byte) error {
   189  	v, err := m.txn.HGet(dbKey, tableKey)
   190  	if err != nil {
   191  		return errors.Trace(err)
   192  	}
   193  
   194  	if v == nil {
   195  		return ErrTableNotExists
   196  	}
   197  
   198  	return nil
   199  }
   200  
   201  func (m *Meta) checkTableNotExists(dbKey []byte, tableKey []byte) error {
   202  	v, err := m.txn.HGet(dbKey, tableKey)
   203  	if err != nil {
   204  		return errors.Trace(err)
   205  	}
   206  
   207  	if v != nil {
   208  		return ErrTableExists
   209  	}
   210  
   211  	return nil
   212  }
   213  
   214  // CreateDatabase creates a database with db info.
   215  func (m *Meta) CreateDatabase(dbInfo *model.DBInfo) error {
   216  	dbKey := m.dbKey(dbInfo.ID)
   217  
   218  	if err := m.checkDBNotExists(dbKey); err != nil {
   219  		return errors.Trace(err)
   220  	}
   221  
   222  	data, err := json.Marshal(dbInfo)
   223  	if err != nil {
   224  		return errors.Trace(err)
   225  	}
   226  
   227  	return m.txn.HSet(mDBs, dbKey, data)
   228  }
   229  
   230  // UpdateDatabase updates a database with db info.
   231  func (m *Meta) UpdateDatabase(dbInfo *model.DBInfo) error {
   232  	dbKey := m.dbKey(dbInfo.ID)
   233  
   234  	if err := m.checkDBExists(dbKey); err != nil {
   235  		return errors.Trace(err)
   236  	}
   237  
   238  	data, err := json.Marshal(dbInfo)
   239  	if err != nil {
   240  		return errors.Trace(err)
   241  	}
   242  
   243  	return m.txn.HSet(mDBs, dbKey, data)
   244  }
   245  
   246  // CreateTable creates a table with tableInfo in database.
   247  func (m *Meta) CreateTable(dbID int64, tableInfo *model.TableInfo) error {
   248  	// Check if db exists.
   249  	dbKey := m.dbKey(dbID)
   250  	if err := m.checkDBExists(dbKey); err != nil {
   251  		return errors.Trace(err)
   252  	}
   253  
   254  	// Check if table exists.
   255  	tableKey := m.tableKey(tableInfo.ID)
   256  	if err := m.checkTableNotExists(dbKey, tableKey); err != nil {
   257  		return errors.Trace(err)
   258  	}
   259  
   260  	data, err := json.Marshal(tableInfo)
   261  	if err != nil {
   262  		return errors.Trace(err)
   263  	}
   264  
   265  	return m.txn.HSet(dbKey, tableKey, data)
   266  }
   267  
   268  // DropDatabase drops whole database.
   269  func (m *Meta) DropDatabase(dbID int64) error {
   270  	// Check if db exists.
   271  	dbKey := m.dbKey(dbID)
   272  	if err := m.txn.HClear(dbKey); err != nil {
   273  		return errors.Trace(err)
   274  	}
   275  
   276  	if err := m.txn.HDel(mDBs, dbKey); err != nil {
   277  		return errors.Trace(err)
   278  	}
   279  
   280  	return nil
   281  }
   282  
   283  // DropTable drops table in database.
   284  func (m *Meta) DropTable(dbID int64, tableID int64) error {
   285  	// Check if db exists.
   286  	dbKey := m.dbKey(dbID)
   287  	if err := m.checkDBExists(dbKey); err != nil {
   288  		return errors.Trace(err)
   289  	}
   290  
   291  	// Check if table exists.
   292  	tableKey := m.tableKey(tableID)
   293  	if err := m.checkTableExists(dbKey, tableKey); err != nil {
   294  		return errors.Trace(err)
   295  	}
   296  
   297  	if err := m.txn.HDel(dbKey, tableKey); err != nil {
   298  		return errors.Trace(err)
   299  	}
   300  
   301  	if err := m.txn.HDel(dbKey, m.autoTalbeIDKey(tableID)); err != nil {
   302  		return errors.Trace(err)
   303  	}
   304  
   305  	return nil
   306  }
   307  
   308  // UpdateTable updates the table with table info.
   309  func (m *Meta) UpdateTable(dbID int64, tableInfo *model.TableInfo) error {
   310  	// Check if db exists.
   311  	dbKey := m.dbKey(dbID)
   312  	if err := m.checkDBExists(dbKey); err != nil {
   313  		return errors.Trace(err)
   314  	}
   315  
   316  	// Check if table exists.
   317  	tableKey := m.tableKey(tableInfo.ID)
   318  	if err := m.checkTableExists(dbKey, tableKey); err != nil {
   319  		return errors.Trace(err)
   320  	}
   321  
   322  	data, err := json.Marshal(tableInfo)
   323  	if err != nil {
   324  		return errors.Trace(err)
   325  	}
   326  
   327  	err = m.txn.HSet(dbKey, tableKey, data)
   328  	return errors.Trace(err)
   329  }
   330  
   331  // ListTables shows all tables in database.
   332  func (m *Meta) ListTables(dbID int64) ([]*model.TableInfo, error) {
   333  	dbKey := m.dbKey(dbID)
   334  	if err := m.checkDBExists(dbKey); err != nil {
   335  		return nil, errors.Trace(err)
   336  	}
   337  
   338  	res, err := m.txn.HGetAll(dbKey)
   339  	if err != nil {
   340  		return nil, errors.Trace(err)
   341  	}
   342  
   343  	tables := make([]*model.TableInfo, 0, len(res)/2)
   344  	for _, r := range res {
   345  		// only handle table meta
   346  		tableKey := string(r.Field)
   347  		if !strings.HasPrefix(tableKey, mTablePrefix) {
   348  			continue
   349  		}
   350  
   351  		tbInfo := &model.TableInfo{}
   352  		err = json.Unmarshal(r.Value, tbInfo)
   353  		if err != nil {
   354  			return nil, errors.Trace(err)
   355  		}
   356  
   357  		tables = append(tables, tbInfo)
   358  	}
   359  
   360  	return tables, nil
   361  }
   362  
   363  // ListDatabases shows all databases.
   364  func (m *Meta) ListDatabases() ([]*model.DBInfo, error) {
   365  	res, err := m.txn.HGetAll(mDBs)
   366  	if err != nil {
   367  		return nil, errors.Trace(err)
   368  	}
   369  
   370  	dbs := make([]*model.DBInfo, 0, len(res))
   371  	for _, r := range res {
   372  		dbInfo := &model.DBInfo{}
   373  		err = json.Unmarshal(r.Value, dbInfo)
   374  		if err != nil {
   375  			return nil, errors.Trace(err)
   376  		}
   377  		dbs = append(dbs, dbInfo)
   378  	}
   379  	return dbs, nil
   380  }
   381  
   382  // GetDatabase gets the database value with ID.
   383  func (m *Meta) GetDatabase(dbID int64) (*model.DBInfo, error) {
   384  	dbKey := m.dbKey(dbID)
   385  	value, err := m.txn.HGet(mDBs, dbKey)
   386  	if err != nil || value == nil {
   387  		return nil, errors.Trace(err)
   388  	}
   389  
   390  	dbInfo := &model.DBInfo{}
   391  	err = json.Unmarshal(value, dbInfo)
   392  	return dbInfo, errors.Trace(err)
   393  }
   394  
   395  // GetTable gets the table value in database with tableID.
   396  func (m *Meta) GetTable(dbID int64, tableID int64) (*model.TableInfo, error) {
   397  	// Check if db exists.
   398  	dbKey := m.dbKey(dbID)
   399  	if err := m.checkDBExists(dbKey); err != nil {
   400  		return nil, errors.Trace(err)
   401  	}
   402  
   403  	tableKey := m.tableKey(tableID)
   404  	value, err := m.txn.HGet(dbKey, tableKey)
   405  	if err != nil || value == nil {
   406  		return nil, errors.Trace(err)
   407  	}
   408  
   409  	tableInfo := &model.TableInfo{}
   410  	err = json.Unmarshal(value, tableInfo)
   411  	return tableInfo, errors.Trace(err)
   412  }
   413  
   414  // DDL job structure
   415  //	DDLOnwer: []byte
   416  //	DDLJobList: list jobs
   417  //	DDLJobHistory: hash
   418  //	DDLJobReorg: hash
   419  //
   420  // for multi DDL workers, only one can become the owner
   421  // to operate DDL jobs, and dispatch them to MR Jobs.
   422  
   423  var (
   424  	mDDLJobOwnerKey   = []byte("DDLJobOwner")
   425  	mDDLJobListKey    = []byte("DDLJobList")
   426  	mDDLJobHistoryKey = []byte("DDLJobHistory")
   427  	mDDLJobReorgKey   = []byte("DDLJobReorg")
   428  )
   429  
   430  func (m *Meta) getJobOwner(key []byte) (*model.Owner, error) {
   431  	value, err := m.txn.Get(key)
   432  	if err != nil || value == nil {
   433  		return nil, errors.Trace(err)
   434  	}
   435  
   436  	owner := &model.Owner{}
   437  	err = json.Unmarshal(value, owner)
   438  	return owner, errors.Trace(err)
   439  }
   440  
   441  // GetDDLJobOwner gets the current owner for DDL.
   442  func (m *Meta) GetDDLJobOwner() (*model.Owner, error) {
   443  	return m.getJobOwner(mDDLJobOwnerKey)
   444  }
   445  
   446  func (m *Meta) setJobOwner(key []byte, o *model.Owner) error {
   447  	b, err := json.Marshal(o)
   448  	if err != nil {
   449  		return errors.Trace(err)
   450  	}
   451  	return m.txn.Set(key, b)
   452  }
   453  
   454  // SetDDLJobOwner sets the current owner for DDL.
   455  func (m *Meta) SetDDLJobOwner(o *model.Owner) error {
   456  	return m.setJobOwner(mDDLJobOwnerKey, o)
   457  }
   458  
   459  func (m *Meta) enQueueDDLJob(key []byte, job *model.Job) error {
   460  	b, err := job.Encode()
   461  	if err != nil {
   462  		return errors.Trace(err)
   463  	}
   464  	return m.txn.RPush(key, b)
   465  }
   466  
   467  // EnQueueDDLJob adds a DDL job to the list.
   468  func (m *Meta) EnQueueDDLJob(job *model.Job) error {
   469  	return m.enQueueDDLJob(mDDLJobListKey, job)
   470  }
   471  
   472  func (m *Meta) deQueueDDLJob(key []byte) (*model.Job, error) {
   473  	value, err := m.txn.LPop(key)
   474  	if err != nil || value == nil {
   475  		return nil, errors.Trace(err)
   476  	}
   477  
   478  	job := &model.Job{}
   479  	err = job.Decode(value)
   480  	return job, errors.Trace(err)
   481  }
   482  
   483  // DeQueueDDLJob pops a DDL job from the list.
   484  func (m *Meta) DeQueueDDLJob() (*model.Job, error) {
   485  	return m.deQueueDDLJob(mDDLJobListKey)
   486  }
   487  
   488  func (m *Meta) getDDLJob(key []byte, index int64) (*model.Job, error) {
   489  	value, err := m.txn.LIndex(key, index)
   490  	if err != nil || value == nil {
   491  		return nil, errors.Trace(err)
   492  	}
   493  
   494  	job := &model.Job{}
   495  	err = job.Decode(value)
   496  	return job, errors.Trace(err)
   497  }
   498  
   499  // GetDDLJob returns the DDL job with index.
   500  func (m *Meta) GetDDLJob(index int64) (*model.Job, error) {
   501  	job, err := m.getDDLJob(mDDLJobListKey, index)
   502  	return job, errors.Trace(err)
   503  }
   504  
   505  func (m *Meta) updateDDLJob(index int64, job *model.Job, key []byte) error {
   506  	// TODO: use timestamp allocated by TSO
   507  	job.LastUpdateTS = time.Now().UnixNano()
   508  	b, err := job.Encode()
   509  	if err != nil {
   510  		return errors.Trace(err)
   511  	}
   512  	return m.txn.LSet(key, index, b)
   513  }
   514  
   515  // UpdateDDLJob updates the DDL job with index.
   516  func (m *Meta) UpdateDDLJob(index int64, job *model.Job) error {
   517  	return m.updateDDLJob(index, job, mDDLJobListKey)
   518  }
   519  
   520  // DDLJobQueueLen returns the DDL job queue length.
   521  func (m *Meta) DDLJobQueueLen() (int64, error) {
   522  	return m.txn.LLen(mDDLJobListKey)
   523  }
   524  
   525  func (m *Meta) jobIDKey(id int64) []byte {
   526  	b := make([]byte, 8)
   527  	binary.BigEndian.PutUint64(b, uint64(id))
   528  	return b
   529  }
   530  
   531  func (m *Meta) addHistoryDDLJob(key []byte, job *model.Job) error {
   532  	b, err := job.Encode()
   533  	if err != nil {
   534  		return errors.Trace(err)
   535  	}
   536  
   537  	return m.txn.HSet(key, m.jobIDKey(job.ID), b)
   538  }
   539  
   540  // AddHistoryDDLJob adds DDL job to history.
   541  func (m *Meta) AddHistoryDDLJob(job *model.Job) error {
   542  	return m.addHistoryDDLJob(mDDLJobHistoryKey, job)
   543  }
   544  
   545  func (m *Meta) getHistoryDDLJob(key []byte, id int64) (*model.Job, error) {
   546  	value, err := m.txn.HGet(key, m.jobIDKey(id))
   547  	if err != nil || value == nil {
   548  		return nil, errors.Trace(err)
   549  	}
   550  
   551  	job := &model.Job{}
   552  	err = job.Decode(value)
   553  	return job, errors.Trace(err)
   554  }
   555  
   556  // GetHistoryDDLJob gets a history DDL job.
   557  func (m *Meta) GetHistoryDDLJob(id int64) (*model.Job, error) {
   558  	return m.getHistoryDDLJob(mDDLJobHistoryKey, id)
   559  }
   560  
   561  // IsBootstrapped returns whether we have already run bootstrap or not.
   562  // return true means we don't need doing any other bootstrap.
   563  func (m *Meta) IsBootstrapped() (bool, error) {
   564  	value, err := m.txn.GetInt64(mBootstrapKey)
   565  	if err != nil {
   566  		return false, errors.Trace(err)
   567  	}
   568  	return value == 1, nil
   569  }
   570  
   571  // FinishBootstrap finishes bootstrap.
   572  func (m *Meta) FinishBootstrap() error {
   573  	err := m.txn.Set(mBootstrapKey, []byte("1"))
   574  	return errors.Trace(err)
   575  }
   576  
   577  // UpdateDDLReorgHandle saves the job reorganization latest processed handle for later resuming.
   578  func (m *Meta) UpdateDDLReorgHandle(job *model.Job, handle int64) error {
   579  	err := m.txn.HSet(mDDLJobReorgKey, m.jobIDKey(job.ID), []byte(strconv.FormatInt(handle, 10)))
   580  	return errors.Trace(err)
   581  }
   582  
   583  // RemoveDDLReorgHandle removes the job reorganization handle.
   584  func (m *Meta) RemoveDDLReorgHandle(job *model.Job) error {
   585  	err := m.txn.HDel(mDDLJobReorgKey, m.jobIDKey(job.ID))
   586  	return errors.Trace(err)
   587  }
   588  
   589  // GetDDLReorgHandle gets the latest processed handle.
   590  func (m *Meta) GetDDLReorgHandle(job *model.Job) (int64, error) {
   591  	value, err := m.txn.HGetInt64(mDDLJobReorgKey, m.jobIDKey(job.ID))
   592  	return value, errors.Trace(err)
   593  }
   594  
   595  // DDL background job structure
   596  //	BgJobOnwer: []byte
   597  //	BgJobList: list jobs
   598  //	BgJobHistory: hash
   599  //	BgJobReorg: hash
   600  //
   601  // for multi background worker, only one can become the owner
   602  // to operate background job, and dispatch them to MR background job.
   603  
   604  var (
   605  	mBgJobOwnerKey   = []byte("BgJobOwner")
   606  	mBgJobListKey    = []byte("BgJobList")
   607  	mBgJobHistoryKey = []byte("BgJobHistory")
   608  )
   609  
   610  // UpdateBgJob updates the background job with index.
   611  func (m *Meta) UpdateBgJob(index int64, job *model.Job) error {
   612  	return m.updateDDLJob(index, job, mBgJobListKey)
   613  }
   614  
   615  // GetBgJob returns the background job with index.
   616  func (m *Meta) GetBgJob(index int64) (*model.Job, error) {
   617  	job, err := m.getDDLJob(mBgJobListKey, index)
   618  
   619  	return job, errors.Trace(err)
   620  }
   621  
   622  // EnQueueBgJob adds a background job to the list.
   623  func (m *Meta) EnQueueBgJob(job *model.Job) error {
   624  	return m.enQueueDDLJob(mBgJobListKey, job)
   625  }
   626  
   627  // BgJobQueueLen returns the background job queue length.
   628  func (m *Meta) BgJobQueueLen() (int64, error) {
   629  	return m.txn.LLen(mBgJobListKey)
   630  }
   631  
   632  // AddHistoryBgJob adds background job to history.
   633  func (m *Meta) AddHistoryBgJob(job *model.Job) error {
   634  	return m.addHistoryDDLJob(mBgJobHistoryKey, job)
   635  }
   636  
   637  // GetHistoryBgJob gets a history background job.
   638  func (m *Meta) GetHistoryBgJob(id int64) (*model.Job, error) {
   639  	return m.getHistoryDDLJob(mBgJobHistoryKey, id)
   640  }
   641  
   642  // DeQueueBgJob pops a background job from the list.
   643  func (m *Meta) DeQueueBgJob() (*model.Job, error) {
   644  	return m.deQueueDDLJob(mBgJobListKey)
   645  }
   646  
   647  // GetBgJobOwner gets the current background job owner.
   648  func (m *Meta) GetBgJobOwner() (*model.Owner, error) {
   649  	return m.getJobOwner(mBgJobOwnerKey)
   650  }
   651  
   652  // SetBgJobOwner sets the current background job owner.
   653  func (m *Meta) SetBgJobOwner(o *model.Owner) error {
   654  	return m.setJobOwner(mBgJobOwnerKey, o)
   655  }
   656  
   657  // meta error codes.
   658  const (
   659  	codeInvalidTableKey terror.ErrCode = 1
   660  	codeInvalidDBKey                   = 2
   661  
   662  	codeDatabaseExists    = 1007
   663  	codeDatabaseNotExists = 1049
   664  	codeTableExists       = 1050
   665  	codeTableNotExists    = 1146
   666  )
   667  
   668  func init() {
   669  	metaMySQLErrCodes := map[terror.ErrCode]uint16{
   670  		codeDatabaseExists:    mysql.ErrDBCreateExists,
   671  		codeDatabaseNotExists: mysql.ErrBadDB,
   672  		codeTableNotExists:    mysql.ErrNoSuchTable,
   673  		codeTableExists:       mysql.ErrTableExists,
   674  	}
   675  	terror.ErrClassToMySQLCodes[terror.ClassMeta] = metaMySQLErrCodes
   676  }