1# 数据库备份与恢复 2 3 4## 场景介绍 5 6当应用在处理一项重要的操作,显然是不能被打断的。例如:写入多个表关联的事务。此时,每个表的写入都是单独的,但是表与表之间的事务关联性不能被分割。 7 8如果操作的过程中出现问题,开发者可以使用恢复功能,将数据库恢复到之前的状态,重新对数据库进行操作。 9 10在数据库被篡改、删除、或者设备断电场景下,数据库可能会因为数据丢失、数据损坏、脏数据等而不可用,可以通过数据库的备份恢复能力将数据库恢复至可用状态。 11 12 13键值型数据库和关系型数据库均支持对数据库的备份和恢复。另外,键值型数据库还支持删除数据库备份,以释放本地存储空间。 14 15 16## 键值型数据库备份、恢复与删除 17 18键值型数据库,通过backup接口实现数据库备份,通过restore接口实现数据库恢复,通过deletebackup接口删除数据库备份。具体接口及功能,可见[分布式键值数据库](../reference/apis/js-apis-distributedKVStore.md)。 19 201. 创建数据库。 21 22 (1) 创建kvManager。 23 24 (2) 配置数据库参数。 25 26 (3) 创建kvStore。 27 28 29 ```ts 30 import distributedKVStore from '@ohos.data.distributedKVStore'; 31 import { BusinessError } from '@ohos.base'; 32 33 let kvManager: distributedKVStore.KVManager; 34 let kvStore: distributedKVStore.SingleKVStore | undefined = undefined; 35 let context = getContext(this); 36 const kvManagerConfig: distributedKVStore.KVManagerConfig = { 37 context: context, 38 bundleName: 'com.example.datamanagertest' 39 } 40 try { 41 kvManager = distributedKVStore.createKVManager(kvManagerConfig); 42 console.info('Succeeded in creating KVManager.'); 43 try { 44 const options: distributedKVStore.Options = { 45 createIfMissing: true, 46 encrypt: true, 47 backup: false, 48 autoSync: true, 49 kvStoreType: distributedKVStore.KVStoreType.SINGLE_VERSION, 50 securityLevel: distributedKVStore.SecurityLevel.S1 51 }; 52 kvManager.getKVStore<distributedKVStore.SingleKVStore>('storeId', options, (err, store: distributedKVStore.SingleKVStore) => { 53 if (err) { 54 console.error(`Failed to get KVStore. Code:${err.code},message:${err.message}`); 55 return; 56 } 57 console.info('Succeeded in getting KVStore.'); 58 kvStore = store; 59 }); 60 } catch (e) { 61 let error = e as BusinessError; 62 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 63 } 64 } catch (e) { 65 let error = e as BusinessError; 66 console.error(`Failed to create KVManager. Code:${error.code},message:${error.message}`); 67 } 68 69 if (kvStore !== undefined) { 70 kvStore = kvStore as distributedKVStore.SingleKVStore; 71 //进行后续操作 72 //... 73 } 74 ``` 75 762. 使用put()方法插入数据。 77 78 ```ts 79 const KEY_TEST_STRING_ELEMENT = 'key_test_string'; 80 const VALUE_TEST_STRING_ELEMENT = 'value_test_string'; 81 try { 82 kvStore.put(KEY_TEST_STRING_ELEMENT, VALUE_TEST_STRING_ELEMENT, (err) => { 83 if (err !== undefined) { 84 console.error(`Fail to put data. Code:${err.code},message:${err.message}`); 85 return; 86 } 87 console.info('Succeeded in putting data.'); 88 }); 89 } catch (e) { 90 let error = e as BusinessError; 91 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 92 } 93 ``` 94 953. 使用backup()方法备份数据。 96 97 ```ts 98 let file = 'BK001'; 99 try { 100 kvStore.backup(file, (err) => { 101 if (err) { 102 console.error(`Fail to backup data.code:${err.code},message:${err.message}`); 103 } else { 104 console.info('Succeeded in backupping data.'); 105 } 106 }); 107 } catch (e) { 108 let error = e as BusinessError; 109 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 110 } 111 ``` 112 1134. 使用delete()方法删除数据(模拟意外删除、篡改场景)。 114 115 ```ts 116 try { 117 kvStore.delete(KEY_TEST_STRING_ELEMENT, (err) => { 118 if (err !== undefined) { 119 console.error(`Fail to delete data. Code:${err.code},message:${err.message}`); 120 return; 121 } 122 console.info('Succeeded in deleting data.'); 123 }); 124 } catch (e) { 125 let error = e as BusinessError; 126 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 127 } 128 ``` 129 1305. 使用restore()方法恢复数据。 131 132 ```ts 133 let file = 'BK001'; 134 try { 135 kvStore.restore(file, (err) => { 136 if (err) { 137 console.error(`Fail to restore data. Code:${err.code},message:${err.message}`); 138 } else { 139 console.info('Succeeded in restoring data.'); 140 } 141 }); 142 } catch (e) { 143 let error = e as BusinessError; 144 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 145 } 146 ``` 147 1486. 当本地设备存储空间有限或需要重新备份时,还可使用deleteBackup()方法删除备份,释放存储空间。 149 150 ```ts 151 let files = ['BK001']; 152 try { 153 kvStore.deleteBackup(files).then((data) => { 154 console.info(`Succeed in deleting Backup. Data:filename is ${data[0]},result is ${data[1]}.`); 155 }).catch((err: BusinessError) => { 156 console.error(`Fail to delete Backup. Code:${err.code},message:${err.message}`); 157 }) 158 } catch (e) { 159 let error = e as BusinessError; 160 console.error(`An unexpected error occurred. Code:${error.code},message:${error.message}`); 161 } 162 ``` 163 164 165## 关系型数据库备份与恢复 166 167关系型数据库,通过backup接口实现数据库备份,通过restore接口实现数据库恢复。具体接口及功能,可见[关系型数据库](../reference/apis/js-apis-data-relationalStore.md)。 168 1691. 使用getRdbStore()方法创建关系型数据库。 170 171 ```ts 172 import relationalStore from '@ohos.data.relationalStore'; 173 import { BusinessError } from '@ohos.base'; 174 175 let store: relationalStore.RdbStore | undefined = undefined; 176 177 let context = getContext(this); 178 179 const STORE_CONFIG: relationalStore.StoreConfig = { 180 name: 'RdbTest.db', 181 securityLevel: relationalStore.SecurityLevel.S1 182 }; 183 relationalStore.getRdbStore(context, STORE_CONFIG, (err, rdbStore) => { 184 store = rdbStore; 185 if (err) { 186 console.error(`Failed to get RdbStore. Code:${err.code},message:${err.message}`); 187 return; 188 } 189 store.executeSql('CREATE TABLE IF NOT EXISTS EMPLOYEE (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER, SALARY REAL, CODES BLOB)', (err) => { 190 }) 191 console.info('Succeeded in getting RdbStore.'); 192 }) 193 ``` 194 1952. 使用insert()方法插入数据。 196 197 ```ts 198 import { ValuesBucket } from '@ohos.data.ValuesBucket'; 199 200 let value1 = 'Rose'; 201 let value2 = 18; 202 let value3 = 100.5; 203 let value4 = new Uint8Array([1, 2, 3, 4, 5]); 204 205 // 以下三种方式可用 206 const valueBucket1: ValuesBucket = { 207 'NAME': value1, 208 'AGE': value2, 209 'SALARY': value3, 210 'CODES': value4, 211 }; 212 const valueBucket2: ValuesBucket = { 213 NAME: value1, 214 AGE: value2, 215 SALARY: value3, 216 CODES: value4, 217 }; 218 const valueBucket3: ValuesBucket = { 219 "NAME": value1, 220 "AGE": value2, 221 "SALARY": value3, 222 "CODES": value4, 223 }; 224 225 if(store != undefined) { 226 (store as relationalStore.RdbStore).insert('EMPLOYEE', valueBucket1, relationalStore.ConflictResolution.ON_CONFLICT_REPLACE, (err, rowId) => { 227 if (err) { 228 console.error(`Failed to insert data. Code:${err.code},message:${err.message}`); 229 return; 230 } 231 console.info(`Succeeded in inserting data. rowId:${rowId}`); 232 }) 233 } 234 ``` 235 2363. 使用backup()方法备份数据。 237 238 ```ts 239 if(store != undefined) { 240 (store as relationalStore.RdbStore).backup('dbBackup.db', (err) => { 241 if (err) { 242 console.error(`Failed to backup data. Code:${err.code},message:${err.message}`); 243 return; 244 } 245 console.info('Succeeded in backuping data.'); 246 }) 247 } 248 ``` 249 2504. 使用delete()方法删除数据(模拟意外删除、篡改场景)。 251 252 ```ts 253 let predicates = new relationalStore.RdbPredicates('EMPLOYEE'); 254 predicates.equalTo('NAME', 'Lisa'); 255 if(store != undefined) { 256 (store as relationalStore.RdbStore).delete(predicates).then((rows: number) => { 257 console.info(`Delete rows: ${rows}`); 258 }).catch((err: BusinessError) => { 259 console.error(`Failed to delete data. Code:${err.code},message:${err.message}`); 260 }) 261 } 262 ``` 263 2645. 使用restore()方法恢复数据。 265 266 ```ts 267 if(store != undefined) { 268 (store as relationalStore.RdbStore).restore('dbBackup.db', (err) => { 269 if (err) { 270 console.error(`Failed to restore data. Code:${err.code},message:${err.message}`); 271 return; 272 } 273 console.info('Succeeded in restoring data.'); 274 }) 275 } 276 ``` 277