Repository navigation
Conversation
|
Please note that the test_sanity critic failure is the |
…ges from flag_activity
… drop the backfill script
…net change per request
…the user activity stats
…vity change in the bug modal
…questee is removed
…ield and the activity by product
|
Also in this push, fixed some issues and optimized SQL request:
The PR description is updated too. |
| 'INSERT INTO flag_activity | ||
| (flag_when, type_id, flag_id, setter_id, who, requestee_id, bug_id, | ||
| attachment_id, status) | ||
| SELECT modification_date, type_id, id, setter_id, setter_id, |
There was a problem hiding this comment.
flags.modification_date is nullable but flag_activity.flag_when is NOT NULL, so a single flag with a null date makes checksetup die here, maybe use COALESCE(modification_date, creation_date)
There was a problem hiding this comment.
Good catch, thanks!
Fixed in 873f583 with your COALESCE(modification_date, creation_date) and a new check in t/flag-activity-start-rows.t (checksetup dies without the fix).
…vity, with a selenium test
…m and changedto searches, with tests
… and the user activity, with tests
| return "EXISTS ( | ||
| SELECT 1 FROM flag_activity $prev | ||
| WHERE $prev.id = (SELECT MAX(p2.id) FROM flag_activity p2 | ||
| WHERE p2.flag_id = $fa.flag_id AND p2.id < $fa.id) |
There was a problem hiding this comment.
reuse FlagActivity->previous_id_sql here so changedfrom matches what history shows as removed (MAX(id) can pick an intermediate row from the same request)
There was a problem hiding this comment.
Fixed in 2635ec3: changedfrom now uses previous_id_sql. It also uses last_of_request_sql, like changedto, so a request is one net change as in history. New checks in t/flag-activity-search.t, which fail without the fix.
| FROM flag_activity fa | ||
| INNER JOIN bugs ON bugs.bug_id = fa.bug_id | ||
| INNER JOIN products ON products.id = bugs.product_id | ||
| WHERE fa.who = ? AND $newer |
There was a problem hiding this comment.
add last_of_request_sql (and skip no-op changes) so per-product counts match history, bugs_activity used to log one combined flag row per request
There was a problem hiding this comment.
Fixed in 0059875: the per-product count now uses last_of_request_sql and skips no-op changes. New check in t/flag-activity-user-stats.t, which fails without the fix.
| . $dbh->sql_date_format('fsa.flag_when', '%Y-%m-%d %H:%i:%s') | ||
| . " AS ts, | ||
| CASE WHEN prev.id IS NULL THEN '' | ||
| WHEN prev.status = '?' AND preq.login_name IS NOT NULL |
There was a problem hiding this comment.
literal '?' in the new CASE breaks the debug placeholder substitution further down, maybe build the status strings without a bare ?
There was a problem hiding this comment.
Good catch, thanks!
Fixed in 97fa12e: the CASE no longer has a bare ?. It compares with CHAR(63) and builds the string from the status column.
Checked on MySQL with a throwaway test calling the report, as it needs CONVERT_TZ and so can't run in the SQLite tests, no committed test: the report rows are unchanged, and the debug SQL now has no ? left and runs, finding the flag rows. It fails without the fix.
|
Along with your comments, I fixed three other issues, each with a test:
The last one and the per-product count add a correlated subquery per row. It's covered by the index from the previous round, but I didn't measure it at production scale. |
| # bugs_activity, which has them all; flag_activity has only some of them, | ||
| # written to both tables, which must not be listed twice. Older rows also don't | ||
| # always know their who: it was filled in from the setter. | ||
| sub newer_than_bugs_activity_sql { |
There was a problem hiding this comment.
per-bug MAX(bug_when) cutoff hides flag_activity rows whenever a later flagtypes.name row lands in bugs_activity, e.g. an old pod still writing both tables during the rolling deploy makes earlier flag_activity-only changes on that bug vanish from history, reports and changedby search, could we use a fixed cutoff stored at migration time instead
There was a problem hiding this comment.
Yes sure, would a row in the params table (written once by checksetup, undeclared param then it won't appear in admin UI) works for you, or would you prefer a dedicated one-row table (most explicit but it's a schema change for a single value)?
There was a problem hiding this comment.
a dedicated one-row table please. an undeclared param doesn't survive well: migrate_params in Bugzilla/Config.pm drops params with no definition from the hash on every checksetup run and then pushes that hash to memcached, so Bugzilla->params loses the value even though the db row is still there (saving editparams does the same). a table like flag_activity_migration (cutoff DATETIME NOT NULL) filled once with NOW() next to the start rows, then read once per request via request_cache, keeps it out of the admin ui and is easy to drop later. with a fixed cutoff, bugs_activity flag rows need bug_when <= cutoff and flag_activity rows need flag_when > cutoff, and the per-row subquery and bugs_activity_bug_field_when_idx can probably go
There was a problem hiding this comment.
Thanks, and you're right about migrate_params, I missed that. I'll do it as you describe:
flag_activity_migration (cutoff DATETIME NOT NULL), filled once withLOCALTIMESTAMP(0)at the end of the start rows migration, which also uses it as its run-once guard. Read once per request throughrequest_cache.flag_activityrows after the cutoff, andbugs_activityflag rows up to it in the readers that list or count changes: history, bugmail, the user activity report and the per-product counts. The ones that take aMAXor anEXISTS(non-bot last change, last user activity, touched, the search conditions, ReleaseTracking) only need theflag_activityside, as a change listed twice doesn't change their result.- The per-row subquery and
bugs_activity_bug_field_when_idxgo away.
I'll push it with the NOT NULL step once #2808 is merged.
There was a problem hiding this comment.
Done as described:
flag_activity_migration (cutoff) is filled with LOCALTIMESTAMP(0) at the end of the start rows migration, which uses it as its run-once guard, and Bugzilla::FlagActivity->cutoff reads it once per request. History, bugmail, the user activity report and the per-product counts read the bugs_activity flag rows up to the cutoff and the flag_activity rows after it. The other readers only use the flag_activity side. bugs_activity_bug_field_when_idx is gone.
The tests set the cutoff with a new set_flag_activity_cutoff helper in Bugzilla::Test::Util. The history and user stats tests also have a change after the cutoff written to both tables, as a pod on the older code does, and check that it's listed and counted once.
Fixed in 3c0d478
# Conflicts: # t/bmo/bugmail-flag-events.t
| {TYPE => 'INT3', REFERENCES => {TABLE => 'profiles', COLUMN => 'userid'}}) | ||
| if !$who; | ||
| $dbh->do('UPDATE flag_activity SET who = setter_id WHERE who IS NULL'); | ||
| $dbh->bz_alter_column('flag_activity', 'who', |
There was a problem hiding this comment.
during the rolling deploy old pods still insert into flag_activity without who. strict mode is turned off in Bugzilla/DB/Mysql.pm so mysql fills in 0, then the new fk to profiles rejects it and flag changes on old pods fail until the rollout ends (if the fk isn't there yet, the row is saved with who = 0 and the inner join on profiles in history drops it). could we ship this in two steps: first add who as nullable and write it while still writing bugs_activity, then make it NOT NULL and stop writing bugs_activity in a follow-up. or at least keep the column nullable for now and backfill who = setter_id WHERE who IS NULL OR who = 0 on every checksetup run
There was a problem hiding this comment.
Right, thanks! I went with the two steps:
- Bug 2088705 - Record the acting user in flag_activity.who, as a nullable column #2808 (bug 2088705) adds
whoas a nullable column, with its foreign key and index, and writes it on every flag change, still writingbugs_activity. checksetup fillswho = setter_idon the rows without it, on every run. - Once it's deployed, this PR makes
whoNOT NULL (after checksetup has filled the rows left without it) and stops writingbugs_activity. During its rolling deploy, the old pods already writewho.
So #2808 needs to go out in an earlier release than this one, I'll update this PR once #2808 is merged.
There was a problem hiding this comment.
Done in 5c3d058
master with #2808 is merged in, and _set_flag_activity_who_not_null makes who NOT NULL right after _add_flag_activity_who has filled the rows left without it.
Checking it on MySQL showed one more thing: once #2808 has added the foreign key, MySQL refuses to make who NOT NULL ("Cannot change column 'who': used in a foreign key constraint"). The step now drops the key first, and bz_setup_foreign_keys adds it back at the end of checksetup, as the oauth2 migration does.
| # bugs_activity, which has them all; flag_activity has only some of them, | ||
| # written to both tables, which must not be listed twice. Older rows also don't | ||
| # always know their who: it was filled in from the setter. | ||
| sub newer_than_bugs_activity_sql { |
There was a problem hiding this comment.
a dedicated one-row table please. an undeclared param doesn't survive well: migrate_params in Bugzilla/Config.pm drops params with no definition from the hash on every checksetup run and then pushes that hash to memcached, so Bugzilla->params loses the value even though the db row is still there (saving editparams does the same). a table like flag_activity_migration (cutoff DATETIME NOT NULL) filled once with NOW() next to the start rows, then read once per request via request_cache, keeps it out of the admin ui and is easy to drop later. with a fixed cutoff, bugs_activity flag rows need bug_when <= cutoff and flag_activity rows need flag_when > cutoff, and the per-row subquery and bugs_activity_bug_field_when_idx can probably go
# Conflicts: # Bugzilla/DB/Schema.pm # Bugzilla/Install/DB.pm # t/flag-activity-who.t
…ctivity, the later ones from flag_activity
Summary
Stops writing flag changes to
bugs_activity: new ones are only recorded inflag_activity, and everything that reads flag changes now reads both tables,bugs_activityfor the changes up to a cutoff stored at checksetup andflag_activityfor the later ones.Part 2 of 1806896, whose part 1 (#2657) moved
flag_state_activityto core asflag_activityand writes every flag change to both tables.Changes
Bugzilla::BugandBugzilla::Attachmentno longer logflagtypes.nametobugs_activity; the user merge ineditusers.cgiwrites its flag changes toflag_activity.flag_activity.who, the user who made the change, becomes NOT NULL. #2808 (bug 2088705) added it as a nullable column and writes it on every change, so it must be deployed in an earlier release than this PR. On MySQL its foreign key is dropped for the change and added back at the end of checksetup.flag_activityrow (flags last changed beforeflag_activitylogged every type) a row with its current state, dated at its last change, in batches of 10,000 flags. History and bugmail don't show it, but the flag's next change gets its previous state. It then stores the cutoff, the time it ran, in the new one-row tableflag_activity_migration, which also keeps it from running again.GetBugActivity), bugmail (_get_diffs), the BMO user activity report and the UserProfile per-product counts read theflagtypes.namerows inbugs_activityup to the cutoff and theflag_activityrows after it (Bugzilla::FlagActivity->cutoff), so a change written to both tables, by a pod still on the older code during the deploy, is listed once. A request that changes a flag several times shows its net change, compared with the flag's last row before the request.changedbefore/changedafter/changedfrom/changedto/changedby/everchangedon flags, and the ReleaseTracking report, match either table.flag_idinflag_activity.flag_activity: the non-bot last change time, the UserProfile stats, the TagNewUsers first activity, owner idle time, andchanged*searches on any field.flag_activityrows can only be deactivated, not deleted, as its history would be deleted with it. The user deletion check ineditusers.cgicountsflag_activityrows, andscripts/remove-non-public-data.plkeepswho.t/flag-activity-history.t,-search.t,-who.t,-user-stats.t,-stream.t,-start-rows.tandt/flag-type-delete.t. They set the cutoff with the newset_flag_activity_cutoffinBugzilla::Test::Util.The old
flagtypes.namerows stay inbugs_activity; nothing is deleted.Test plan
bugs_activitygets no newflagtypes.namerowneedinfo?" and the user activity report find both older and new changeseditusers.cgi: the reassigned requests appear in bug historyReferences