| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // OSS Migration: Hangzhou → Shanghai (internal endpoint)
- // Server is in cn-shanghai, bucket must be same region for internal access
- const OSS = require('ali-oss');
- const mysql = require('mysql2/promise');
- const AK = 'LTAI5tBn4G5HMo8PqMdNsqHd';
- const SK = 'f0R5nOQf6E1lIGESENKiK8cNzFl8wd';
- const OLD_BUCKET = 'aaaa33dfsf32rfsf';
- const OLD_REGION = 'oss-cn-hangzhou';
- const NEW_BUCKET = 'aaaa33dfsf32rfsf-sh';
- const NEW_REGION = 'oss-cn-shanghai';
- async function main() {
- // Source: Hangzhou PUBLIC endpoint (internal is broken cross-region)
- const src = new OSS({
- region: OLD_REGION,
- accessKeyId: AK,
- accessKeySecret: SK,
- bucket: OLD_BUCKET,
- secure: true,
- internal: false, // public endpoint
- });
- // Dest: Shanghai INTERNAL endpoint
- const dst = new OSS({
- region: NEW_REGION,
- accessKeyId: AK,
- accessKeySecret: SK,
- bucket: NEW_BUCKET,
- secure: true,
- internal: true,
- });
- console.log('[1/4] Listing objects in Hangzhou bucket...');
- let allObjects = [];
- let marker = null;
- do {
- const result = await src.list({ 'max-keys': 100, marker });
- if (result.objects) allObjects.push(...result.objects);
- marker = result.nextMarker;
- } while (marker);
- console.log(` Found ${allObjects.length} objects`);
- if (allObjects.length === 0) {
- console.log(' No objects to migrate!');
- return;
- }
- console.log('[2/4] Copying objects to Shanghai bucket...');
- let copied = 0, failed = 0;
- for (const obj of allObjects) {
- try {
- // Download from Hangzhou public
- const data = await src.get(obj.name);
- // Upload to Shanghai internal (ACL inherited from bucket)
- await dst.put(obj.name, data.content, {
- mime: data.res?.headers?.['content-type'] || 'audio/mpeg',
- });
- copied++;
- if (copied % 20 === 0) console.log(` Progress: ${copied}/${allObjects.length}`);
- } catch (e) {
- failed++;
- console.error(` FAIL ${obj.name}: ${e.message?.slice(0,80)}`);
- }
- }
- console.log(` Done: ${copied} copied, ${failed} failed`);
- // Update env
- console.log('[3/4] Updating environment config...');
- const fs = require('fs');
- const envPath = '/data/ai/audio/server/.env';
- let env = fs.readFileSync(envPath, 'utf-8');
- // Replace bucket name in OSS endpoints
- env = env.replace(/OSS_ENDPOINT=oss-cn-hangzhou/g, 'OSS_ENDPOINT=oss-cn-shanghai');
- env = env.replace(/OSS_INTERNAL_ENDPOINT=oss-cn-hangzhou-internal/g, 'OSS_INTERNAL_ENDPOINT=oss-cn-shanghai-internal');
- env = env.replace(new RegExp(OLD_BUCKET, 'g'), NEW_BUCKET);
- fs.writeFileSync(envPath, env, 'utf-8');
- fs.writeFileSync(envPath + '.bak', env, 'utf-8'); // backup too
- console.log(' Updated .env with Shanghai endpoints & new bucket name');
- // Update DB audioUrl references
- console.log('[4/4] Updating database audioUrl references...');
- const db = await mysql.createConnection('mysql://root:123456@127.0.0.1:3306/audio_book');
- const oldPrefix = `https://${OLD_BUCKET}.${OLD_REGION}.aliyuncs.com/`;
- const newPrefix = `https://${NEW_BUCKET}.${NEW_REGION}.aliyuncs.com/`;
- const [chCount] = await db.execute(
- `UPDATE BookChapter SET audioUrl = REPLACE(audioUrl, ?, ?) WHERE audioUrl LIKE ?`,
- [oldPrefix, newPrefix, `%${OLD_BUCKET}.${OLD_REGION}.aliyuncs.com%`]
- );
- console.log(` BookChapter: ${chCount.changedRows || 0} rows updated`);
- const [arCount] = await db.execute(
- `UPDATE AudioRecord SET audioUrl = REPLACE(audioUrl, ?, ?) WHERE audioUrl LIKE ?`,
- [oldPrefix, newPrefix, `%${OLD_BUCKET}.${OLD_REGION}.aliyuncs.com%`]
- );
- console.log(` AudioRecord: ${arCount.changedRows || 0} rows updated`);
- await db.end();
- console.log('\n=== Migration complete ===');
- console.log(`Copied: ${copied} files`);
- console.log(`Env updated: ${envPath}`);
- console.log(`Restart required: pm2 restart server`);
- }
- main().catch(e => { console.error('FATAL:', e); process.exit(1); });
|