|
| 1 | +#coding:utf-8 |
| 2 | + |
| 3 | +""" |
| 4 | +ID: issue-5868 |
| 5 | +ISSUE: https://github.com/FirebirdSQL/firebird/issues/5868 |
| 6 | +TITLE: Slow changes on domain |
| 7 | +DESCRIPTION: |
| 8 | +JIRA: CORE-5602 |
| 9 | +FBTEST: bugs.core_5602 |
| 10 | +
|
| 11 | +NOTES: |
| 12 | + [08.03.2023] pzotov |
| 13 | + Re-implemented: we have to use psutil package instead of 'fragile' datediff. |
| 14 | + Confirmed bug on 3.0.2.32703 (date of build: 21-mar-2017). |
| 15 | + Timedelta for 'alter domain ... add|drop constraint' could achieve ~110 seconds: |
| 16 | + 2023-03-08T14:27:09.6540 (16460:00000000032C0040) EXECUTE_STATEMENT_START |
| 17 | + alter domain bool_emul drop constraint |
| 18 | + 2023-03-08T14:29:01.0190 (16460:00000000032C0040) EXECUTE_STATEMENT_FINISH |
| 19 | + alter domain bool_emul drop constraint |
| 20 | +
|
| 21 | + Checked on 3.0.11.33665, 4.0.3.2904, 5.0.0.970 |
| 22 | +""" |
| 23 | +import os |
| 24 | +import psutil |
| 25 | +import pytest |
| 26 | +from firebird.qa import * |
| 27 | +import time |
| 28 | + |
| 29 | +#-------------------------------------------------------------------- |
| 30 | +def median(lst): |
| 31 | + n = len(lst) |
| 32 | + s = sorted(lst) |
| 33 | + return (sum(s[n//2-1:n//2+1])/2.0, s[n//2])[n % 2] if n else None |
| 34 | +#-------------------------------------------------------------------- |
| 35 | + |
| 36 | +########################### |
| 37 | +### S E T T I N G S ### |
| 38 | +########################### |
| 39 | +# How many measures we will perform: |
| 40 | +N_MEASURES = 11 |
| 41 | + |
| 42 | +# Maximal value for MEDIAN of ratios between CPU user time when comparison was made, |
| 43 | +# time_for_alter_domain_(add_|_drop)_constraint and time_for_transaction_commit. |
| 44 | +# On march-2023, medians are almost equal and are about 0.35 ... 0.45 (in FB 3.x, 4.x and 5.x) |
| 45 | +# |
| 46 | +############################ |
| 47 | +DEL_2_COMMIT_MAX_RATIO = 0.8 |
| 48 | +ADD_2_COMMIT_MAX_RATIO = 0.8 |
| 49 | +############################ |
| 50 | + |
| 51 | +db = db_factory(from_backup='core5602.fbk') |
| 52 | +act = python_act('db') |
| 53 | + |
| 54 | +@pytest.mark.version('>=3.0.3') |
| 55 | +def test_1(act: Action, capsys): |
| 56 | + time_data = {} |
| 57 | + with act.db.connect() as con: |
| 58 | + cur=con.cursor() |
| 59 | + cur.execute('select mon$server_pid as p from mon$attachments where mon$attachment_id = current_connection') |
| 60 | + fb_pid = int(cur.fetchone()[0]) |
| 61 | + |
| 62 | + for i in range(0, N_MEASURES): |
| 63 | + fb_info_1 = psutil.Process(fb_pid).cpu_times() |
| 64 | + con.execute_immediate(f'alter domain bool_emul drop constraint -- {i}') |
| 65 | + fb_info_2 = psutil.Process(fb_pid).cpu_times() |
| 66 | + con.commit() |
| 67 | + fb_info_3 = psutil.Process(fb_pid).cpu_times() |
| 68 | + time_data[ 'del_constraint', i ] = ( max(fb_info_2.user - fb_info_1.user, 0.000001), max(fb_info_3.user - fb_info_2.user, 0.000001) ) |
| 69 | + |
| 70 | + con.execute_immediate(f"alter domain bool_emul add check (value in ('t', 'f')) -- {i}") |
| 71 | + fb_info_4 = psutil.Process(fb_pid).cpu_times() |
| 72 | + con.commit() |
| 73 | + fb_info_5 = psutil.Process(fb_pid).cpu_times() |
| 74 | + time_data[ 'add_constraint', i ] = ( max(fb_info_4.user - fb_info_3.user, 0.000001), max(fb_info_5.user - fb_info_4.user, 0.000001) ) |
| 75 | + |
| 76 | + |
| 77 | + del_constraint_to_commit_ratios = [ v[0] / v[1] for k,v in time_data.items() if k[0] == 'del_constraint' ] |
| 78 | + add_constraint_to_commit_ratios = [ v[0] / v[1] for k,v in time_data.items() if k[0] == 'add_constraint' ] |
| 79 | + |
| 80 | + #for k,v in sorted(time_data.items()): |
| 81 | + # print(k,':::',v) |
| 82 | + #print(del_constraint_to_commit_ratios) |
| 83 | + #print(add_constraint_to_commit_ratios) |
| 84 | + |
| 85 | + del_constr_to_commit_median = median(del_constraint_to_commit_ratios) |
| 86 | + add_constr_to_commit_median = median(add_constraint_to_commit_ratios) |
| 87 | + |
| 88 | + msg_del_success = 'ALTER DOMAIN DROP CONSTRAINT performed for acceptable time' |
| 89 | + msg_add_success = 'ALTER DOMAIN ADD CONSTRAINT performed for acceptable time' |
| 90 | + |
| 91 | + if del_constr_to_commit_median < DEL_2_COMMIT_MAX_RATIO: |
| 92 | + print(msg_del_success) |
| 93 | + else: |
| 94 | + print('ALTER DOMAIN DROP CONSTRAINT perfomed too slow. Ratios of DML to COMMIT time:') |
| 95 | + for p in del_constraint_to_commit_ratios: |
| 96 | + print('%12.4f' % p) |
| 97 | + print('Median value: %12.4f - GREATER than threshold: %12.4f' % (del_constr_to_commit_median,DEL_2_COMMIT_MAX_RATIO)) |
| 98 | + |
| 99 | + |
| 100 | + if add_constr_to_commit_median < ADD_2_COMMIT_MAX_RATIO: |
| 101 | + print(msg_add_success) |
| 102 | + else: |
| 103 | + print('ALTER DOMAIN ADD CONSTRAINT perfomed too slow. Ratios of DML to COMMIT time:') |
| 104 | + for p in add_constraint_to_commit_ratios: |
| 105 | + print('%12.4f' % p) |
| 106 | + print('Median value: %12.4f - GREATER than threshold: %12.4f' % (add_constr_to_commit_median,ADD_2_COMMIT_MAX_RATIO)) |
| 107 | + |
| 108 | + expected_stdout = ''' |
| 109 | + ALTER DOMAIN DROP CONSTRAINT performed for acceptable time |
| 110 | + ALTER DOMAIN ADD CONSTRAINT performed for acceptable time |
| 111 | + ''' |
| 112 | + |
| 113 | + act.expected_stdout = expected_stdout |
| 114 | + act.stdout = capsys.readouterr().out |
| 115 | + assert act.clean_stdout == act.clean_expected_stdout |
0 commit comments