Guest User

Untitled

a guest
Dec 5th, 2018
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.76 KB | None | 0 0
  1. # TCI Migration (Khorasan Razavi)
  2. We want to move data of following tables from one server (A: Khorasan Razavi) to another server (B: TCI).
  3.  
  4. User tables:
  5. - users
  6. - user_attrs
  7. - normal_users
  8.  
  9. Group table; we only need this table for group mapping:
  10. - groups
  11.  
  12. ## Step 1 (Server A)
  13. Export tables data from server **A** as CSV files and import them into server **B**.
  14.  
  15. Create a directory in `/tmp/` to save our export files:
  16. ```
  17. # rm -rf /tmp/migration_a/
  18. # mkdir /tmp/migration_a/
  19. # chmod 777 /tmp/migration_a/
  20. ```
  21.  
  22. Export User tables data:
  23. ```
  24. IBSng=# COPY (SELECT user_id, isp_id, credit, deposit, deposit_recharge, status, group_id, creation_date, nearest_exp_date FROM users) TO '/tmp/migration_a/migration_a_users.csv' WITH DELIMITER ',';
  25.  
  26. IBSng=# COPY (SELECT user_id, attr_name, attr_value FROM user_attrs) TO '/tmp/migration_a/migration_a_user_attrs.csv' WITH DELIMITER ',';
  27.  
  28. IBSng=# COPY (SELECT user_id, normal_username, normal_password, second_normal_username FROM normal_users) TO '/tmp/migration_a/migration_a_normal_users.csv' WITH DELIMITER ',';
  29. ```
  30.  
  31. Export Group table data:
  32. ```
  33. IBSng=# COPY (SELECT group_id, group_name, status, isp_id, comment FROM groups) TO '/tmp/migration_a/migration_a_groups.csv' WITH DELIMITER ',';
  34. ```
  35.  
  36. Now that we have exported data from the database, we need to move them to server **B**:
  37. ```
  38. # cd /tmp/
  39. # tar zcf migration_a.tar.gz migration_a
  40. # rm -rf migration_a
  41. ```
  42.  
  43. Now we need to move the file `/tmp/migration_a.tar.gz` to server **B** by SCP, FTP, etc.
  44.  
  45. ## Step 2 (Server B)
  46. Suppose we moved exported data files which was generated in step 1 to `/tmp/` directory, now we need to extract them:
  47. ```
  48. # cd /tmp/
  49. # rm -rf migration_a
  50. # tar xf migration_a.tar.gz
  51. # rm -rf migration_a.tar.gz
  52. ```
  53.  
  54. ### Step 2.1
  55. Now we need to create temporary tables and fill them with exported data from server A.
  56.  
  57. Create temporary User tables:
  58. ```
  59. IBSng=# CREATE TABLE migration_a_users AS SELECT user_id, isp_id, credit, deposit, deposit_recharge, status, group_id, creation_date, nearest_exp_date FROM users LIMIT 1;
  60. IBSng=# TRUNCATE migration_a_users;
  61.  
  62. IBSng=# CREATE TABLE migration_a_user_attrs AS SELECT user_id, attr_name, attr_value FROM user_attrs LIMIT 1;
  63. IBSng=# TRUNCATE migration_a_user_attrs;
  64.  
  65. IBSng=# CREATE TABLE migration_a_normal_users AS SELECT user_id, normal_username, normal_password, second_normal_username FROM normal_users LIMIT 1;
  66. IBSng=# TRUNCATE migration_a_normal_users;
  67. ```
  68.  
  69. Create temporary Group table:
  70. ```
  71. IBSng=# CREATE TABLE migration_a_groups AS SELECT group_id, group_name, status, isp_id, comment FROM groups LIMIT 1;
  72. IBSng=# TRUNCATE migration_a_groups;
  73. ```
  74.  
  75. ### Step 2.2
  76. Import data from CSV files of server A to temporary tables we just created;
  77.  
  78. Import User tables data:
  79. ```
  80. IBSng=# COPY migration_a_users (user_id, isp_id, credit, deposit, deposit_recharge, status, group_id, creation_date, nearest_exp_date) FROM '/tmp/migration_a/migration_a_users.csv' WITH DELIMITER ',';
  81.  
  82. IBSng=# COPY migration_a_user_attrs (user_id, attr_name, attr_value) FROM '/tmp/migration_a/migration_a_user_attrs.csv' WITH DELIMITER ',';
  83.  
  84. IBSng=# COPY migration_a_normal_users (user_id, normal_username, normal_password, second_normal_username) FROM '/tmp/migration_a/migration_a_normal_users.csv' WITH DELIMITER ',';
  85. ```
  86.  
  87. Import Group table data:
  88. ```
  89. IBSng=# COPY migration_a_groups (group_id, group_name, status, isp_id, comment) FROM '/tmp/migration_a/migration_a_groups.csv' WITH DELIMITER ',';
  90. ```
  91.  
  92. ### Step 2.3
  93. For this migration we need to clean our imported data according to following requirements:
  94.  
  95. - Convert all user passwords to lower case
  96. - Remove users with no username
  97. - We need to move only some specific attributes of users
  98.  
  99. #### Step 2.3.1
  100. Convert all user passwords to lower case:
  101. ```
  102. IBSng=# UPDATE migration_a_normal_users SET normal_password = LOWER(normal_password);
  103. ```
  104.  
  105. #### Step 2.3.2
  106. Remove users with no username:
  107. ```
  108. IBSng=# CREATE UNIQUE INDEX migration_a_users_user_id_idx ON migration_a_users (user_id);
  109. IBSng=# CREATE UNIQUE INDEX migration_a_normal_users_user_id_idx ON migration_a_normal_users (user_id);
  110.  
  111. IBSng=# CREATE TABLE migration_a_no_username AS SELECT user_id FROM migration_a_users WHERE NOT EXISTS (SELECT migration_a_normal_users.user_id FROM migration_a_normal_users WHERE migration_a_users.user_id = migration_a_normal_users.user_id);
  112. IBSng=# CREATE UNIQUE INDEX migration_a_no_username_user_id_idx ON migration_a_no_username (user_id);
  113.  
  114. IBSng=# DELETE FROM migration_a_users WHERE EXISTS (SELECT migration_a_no_username.user_id FROM migration_a_no_username WHERE migration_a_users.user_id = migration_a_no_username.user_id);
  115. IBSng=# DELETE FROM migration_a_user_attrs WHERE EXISTS (SELECT migration_a_no_username.user_id FROM migration_a_no_username WHERE migration_a_user_attrs.user_id = migration_a_no_username.user_id);
  116.  
  117. IBSng=# DROP TABLE migration_a_no_username;
  118. ```
  119.  
  120. > Note: We need to execute following queries, because we may have dangling records in user tables:
  121. ```
  122. IBSng=# DELETE FROM migration_a_normal_users WHERE NOT EXISTS (SELECT migration_a_users.user_id FROM migration_a_users WHERE migration_a_normal_users.user_id = migration_a_users.user_id);
  123. IBSng=# DELETE FROM migration_a_user_attrs WHERE NOT EXISTS (SELECT migration_a_users.user_id FROM migration_a_users WHERE migration_a_user_attrs.user_id = migration_a_users.user_id);
  124. ```
  125.  
  126. #### Step 2.3.3
  127. We need to move only some specific attributes of users, the attributes are:
  128.  
  129. - abs_exp_date
  130. - address
  131. - assign_dns
  132. - assign_ip
  133. - assign_route_ip
  134. - cell_phone
  135. - comment
  136. - custom_field_center
  137. - custom_field_dedicated_sim_number
  138. - custom_field_document_number
  139. - custom_field_establishing_date
  140. - custom_field_melli_code
  141. - email
  142. - first_login
  143. - lock
  144. - multi_login
  145. - name
  146. - night_free
  147. - phone
  148. - postal_code
  149. - radius_attrs
  150. - real_first_login
  151.  
  152. Write attribute names to `/tmp/migration_a/migration_a_attr_names.csv`:
  153. ```
  154. cat << EOF > /tmp/migration_a/migration_a_attr_names.csv
  155. abs_exp_date
  156. address
  157. assign_dns
  158. assign_ip
  159. assign_route_ip
  160. cell_phone
  161. comment
  162. custom_field_center
  163. custom_field_dedicated_sim_number
  164. custom_field_document_number
  165. custom_field_establishing_date
  166. custom_field_melli_code
  167. email
  168. first_login
  169. lock
  170. multi_login
  171. name
  172. night_free
  173. phone
  174. postal_code
  175. radius_attrs
  176. real_first_login
  177. EOF
  178. ```
  179.  
  180. ```
  181. IBSng=# CREATE TABLE migration_a_attr_names AS SELECT attr_name FROM user_attrs LIMIT 1;
  182. IBSng=# TRUNCATE migration_a_attr_names;
  183. IBSng=# COPY migration_a_attr_names (attr_name) FROM '/tmp/migration_a/migration_a_attr_names.csv' WITH DELIMITER ',';
  184. IBSng=# CREATE UNIQUE INDEX migration_a_attr_names_attr_name_idx ON migration_a_attr_names (attr_name);
  185.  
  186. IBSng=# DELETE FROM migration_a_user_attrs WHERE NOT EXISTS (SELECT migration_a_attr_names.attr_name FROM migration_a_attr_names WHERE migration_a_user_attrs.attr_name = migration_a_attr_names.attr_name);
  187.  
  188. IBSng=# DROP TABLE migration_a_attr_names;
  189. ```
  190.  
  191. ### Step 2.4
  192. To make column ids of temporary tables compatible with server B, we create a new column named `<id_column>_new` and rename the current column name to `<id_column>_old`; then we fill `<id_column>_new` with corresponded values.
  193.  
  194. Add/Rename User tables ID columns:
  195. ```
  196. IBSng=# ALTER TABLE migration_a_users RENAME COLUMN user_id TO user_id_old;
  197. IBSng=# ALTER TABLE migration_a_users ADD COLUMN user_id_new bigint;
  198. IBSng=# ALTER TABLE migration_a_users RENAME COLUMN group_id TO group_id_old;
  199. IBSng=# ALTER TABLE migration_a_users ADD COLUMN group_id_new bigint;
  200.  
  201. IBSng=# ALTER TABLE migration_a_user_attrs RENAME COLUMN user_id TO user_id_old;
  202. IBSng=# ALTER TABLE migration_a_user_attrs ADD COLUMN user_id_new bigint;
  203.  
  204. IBSng=# ALTER TABLE migration_a_normal_users RENAME COLUMN user_id TO user_id_old;
  205. IBSng=# ALTER TABLE migration_a_normal_users ADD COLUMN user_id_new bigint;
  206. ```
  207.  
  208. Add/Rename Group tables ID columns:
  209. ```
  210. IBSng=# ALTER TABLE migration_a_groups RENAME COLUMN group_id TO group_id_old;
  211. IBSng=# ALTER TABLE migration_a_groups ADD COLUMN group_id_new bigint;
  212. ```
  213.  
  214. ### Step 2.5
  215. Fill temporary tables with new IDs.
  216.  
  217. Generate new IDs for User table:
  218. ```
  219. IBSng=# UPDATE migration_a_users SET user_id_new = nextval('users_user_id_seq');
  220. ```
  221.  
  222. Suppose we have a csv file named `migration_a_group_mapping.csv` with two columns in `/tmp/migration_a/` directory:
  223.  
  224. - old group name
  225. - new group ID
  226.  
  227. > Note: The CSV file has no header
  228.  
  229. Now we need to import group mappings to our database (server B):
  230. ```
  231. IBSng=# CREATE TABLE migration_a_group_mapping AS SELECT group_name, group_id FROM groups LIMIT 1;
  232. IBSng=# TRUNCATE migration_a_group_mapping;
  233. IBSng=# ALTER TABLE migration_a_group_mapping RENAME COLUMN group_name TO group_name_old;
  234. IBSng=# ALTER TABLE migration_a_group_mapping RENAME COLUMN group_id TO group_id_new;
  235.  
  236. IBSng=# COPY migration_a_group_mapping (group_name_old, group_id_new) FROM '/tmp/migration_a/migration_a_group_mapping.csv' WITH DELIMITER ',';
  237. ```
  238.  
  239. Fill Group table with new IDs:
  240. ```
  241. IBSng=# UPDATE migration_a_groups SET group_id_new = migration_a_group_mapping.group_id_new FROM migration_a_group_mapping WHERE migration_a_groups.group_name = migration_a_group_mapping.group_name_old;
  242. ```
  243.  
  244. ### Step 2.6
  245. Map old IDs to new IDs and fill corresponded values in temporary tables.
  246.  
  247. Map User tables old IDs to new IDs:
  248. ```
  249. IBSng=# UPDATE migration_a_users SET group_id_new = migration_a_groups.group_id_new FROM migration_a_groups WHERE migration_a_users.group_id_old = migration_a_groups.group_id_old;
  250.  
  251. IBSng=# UPDATE migration_a_user_attrs SET user_id_new = migration_a_users.user_id_new FROM migration_a_users WHERE migration_a_user_attrs.user_id_old = migration_a_users.user_id_old;
  252.  
  253. IBSng=# UPDATE migration_a_normal_users SET user_id_new = migration_a_users.user_id_new FROM migration_a_users WHERE migration_a_normal_users.user_id_old = migration_a_users.user_id_old;
  254. ```
  255.  
  256. > Note: We need to fill `group_id_new` column of `migration_a_users` table with default group of **unknown-group** with ID of **3752**, where we have no group mapping:
  257. ```
  258. IBSng=# UPDATE migration_a_users SET group_id_new = 3752 WHERE group_id_new is NULL;
  259. ```
  260.  
  261. ## Step 3
  262. Update isp_id of records:
  263. ```
  264. IBSng=# UPDATE migration_a_users SET isp_id = <province_isp_id>;
  265. ```
  266.  
  267. > Note: ISP ID of Khorasan Razavi is **40**
  268.  
  269. ## Step 4
  270. Delete users from temporary tables (server A) with the same normal_username in server B:
  271. ```
  272. IBSng=# CREATE TABLE migration_a_users_dup AS SELECT user_id_old as user_id_dup FROM migration_a_normal_users WHERE normal_username IN (SELECT normal_username FROM normal_users);
  273.  
  274. IBSng=# DELETE FROM migration_a_users WHERE user_id_old IN (SELECT user_id_dup FROM migration_a_users_dup);
  275.  
  276. IBSng=# DELETE FROM migration_a_user_attrs WHERE user_id_old IN (SELECT user_id_dup FROM migration_a_users_dup);
  277.  
  278. IBSng=# DELETE FROM migration_a_normal_users WHERE user_id_old IN (SELECT user_id_dup FROM migration_a_users_dup);
  279.  
  280. IBSng=# DROP TABLE migration_a_users_dup;
  281. ```
  282.  
  283. ## Step 5
  284. TODO: Backup from the database and especially a separate backup from tables which are going to be changed.
  285.  
  286. ### Step 5.1
  287. Insert temporary tables records into main tables.
  288.  
  289. Insert User tables records:
  290. ```
  291. IBSng=# INSERT INTO users (user_id, isp_id, credit, deposit, deposit_recharge, status, group_id, creation_date, nearest_exp_date) SELECT user_id_new, isp_id, credit, deposit, deposit_recharge, status, group_id_new, creation_date, nearest_exp_date FROM migration_a_users;
  292.  
  293. IBSng=# ALTER TABLE user_attrs DISABLE TRIGGER update_user_nearest_exp_date_trigger;
  294. IBSng=# INSERT INTO user_attrs (user_id, attr_name, attr_value) SELECT user_id_new, attr_name, attr_value FROM migration_a_user_attrs;
  295. IBSng=# ALTER TABLE user_attrs ENABLE TRIGGER update_user_nearest_exp_date_trigger;
  296.  
  297. IBSng=# ALTER TABLE normal_users DISABLE TRIGGER users_prevent_duplicate_username_trigger;
  298. IBSng=# INSERT INTO normal_users (user_id, normal_username, normal_password, second_normal_username) SELECT user_id_new, normal_username, normal_password, second_normal_username FROM migration_a_normal_users;
  299. IBSng=# ALTER TABLE normal_users ENABLE TRIGGER users_prevent_duplicate_username_trigger;
  300. ```
  301.  
  302. > Note: In inserting records to **normal_users** table, remember to disable the trigger of the table; otherwise it takes a very long time to insert records.
  303.  
  304. ## Step 7
  305. Now that we completed the migration, we need to reload new users.
  306.  
  307. ### Step 7.1
  308. Export IDs of new users.
  309.  
  310. Export User IDs:
  311. ```
  312. IBSng=# COPY (SELECT user_id_new FROM migration_a_users) TO '/tmp/migration_a/migration_a_users_reload.csv' WITH DELIMITER ',';
  313. ```
  314.  
  315. ### Step 7.2
  316. Run reload script for new users. These scripts should be run on master App of IBSng.
  317.  
  318. Move `reload_users_by_csv.py` to `/opt/` and then run User reload script:
  319. ```
  320. # python /usr/local/IBSng/addons/client/client.py -u <web_panel_username> -p <web_panel_password> -i /opt/reload_users_by_csv.py
  321. ```
  322.  
  323. > Source code of `realod_users_by_csv.py` script:
  324. ```python
  325. from core.user import user_main
  326.  
  327. with open("/tmp/migration_a/migration_a_users_reload.csv", "r") as fd:
  328. user_ids = []
  329. for line in fd.readlines():
  330. user_id_str = line.strip("\r\n ")
  331. if user_id_str:
  332. user_ids.append(long(user_id_str))
  333. if len(user_ids) == 10:
  334. user_main.getActionManager().broadcastChange(user_ids)
  335. user_ids = []
  336.  
  337. user_main.getActionManager().broadcastChange(user_ids)
  338. ```
  339.  
  340. ## Notes
  341. Creat mapping files of migrated data for third party applications: (user_id_old, user_id_new, group_name_old, group_name_new, abs_exp_date) and (group_name_old, group_name_new)
  342.  
  343. Export users summary:
  344. ```
  345. IBSng=# ALTER TABLE migration_a_users ADD COLUMN group_name_old text;
  346. IBSng=# ALTER TABLE migration_a_users ADD COLUMN group_name_new text;
  347.  
  348. IBSng=# UPDATE migration_a_users SET group_name_old = migration_a_groups.group_name FROM migration_a_groups WHERE migration_a_users.group_id_old = migration_a_groups.group_id_old;
  349. IBSng=# UPDATE migration_a_users SET group_name_new = groups.group_name FROM groups WHERE migration_a_users.group_id_new = groups.group_id;
  350.  
  351. IBSng=# CREATE TABLE migration_a_users_summary AS SELECT user_id_old, user_id_new, group_name_old, group_name_new FROM migration_a_users;
  352. IBSng=# ALTER TABLE migration_a_users_summary ADD COLUMN abs_exp_date text;
  353. IBSng=# UPDATE migration_a_users_summary SET abs_exp_date = migration_a_user_attrs.attr_value FROM migration_a_user_attrs WHERe migration_a_users_summary.user_id_old = migration_a_user_attrs.user_id_old AND migration_a_user_attrs.attr_name = 'abs_exp_date';
  354.  
  355. IBSng=# COPY (SELECT user_id_old, user_id_new, group_name_old, group_name_new, abs_exp_date FROM migration_a_users_summary) TO '/tmp/migration_a/migration_a_users_summary.csv' WITH DELIMITER ',' CSV HEADER;
  356. ```
  357.  
  358. Export groups summary:
  359. ```
  360. IBSng=# ALTER TABLE migration_a_group_mapping ADD COLUMN group_name_new text;
  361. IBSng=# UPDATE migration_a_group_mapping SET group_name_new = groups.group_name FROM groups WHERE migration_a_group_mapping.group_id_new = groups.group_id;
  362.  
  363. IBSng=# COPY (SELECT group_name_old, group_name_new FROM migration_a_group_mapping) TO '/tmp/migration_a/migration_a_groups_summary.csv' WITH DELIMITER ',' CSV HEADER;
  364. ```
Add Comment
Please, Sign In to add comment