Skip to content

Soft-delete Submissions to reset student state - #33

Merged
efischer19 merged 1 commit into
masterfrom
efischer/soft_delete_sub
Feb 18, 2016
Merged

Soft-delete Submissions to reset student state#33
efischer19 merged 1 commit into
masterfrom
efischer/soft_delete_sub

Conversation

@efischer19

Copy link
Copy Markdown
Contributor

Previous methods of "deleting state" for a student had just issued
reset scores, so the (unscored) submission was still hanging around.
With this change, the submission can be "deleted" for all django-
relevant purposes, while still remaining in the database in case
it turns out to be interesting to analytics later.

Supersedes #32.
Sibling change to https://github.com/edx/edx-platform/pull/11371 and openedx/edx-ora2#862

Comment thread submissions/models.py Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mulby, I'm curious if this approach to soft-deleting will meet everyone's needs. By overriding the objects manager for the relevant classes, we'll essentially be hiding the deleted records from any query internal to the djangoapp.

When the data is gathered for analytics, is it accessed using django models (e.g. Submissions.objects.all()), or taken straight from the database using other methods? Is the same true for instuctor-initiated data downloads?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we export to researchers we just dump the data directly out of the database using a MySQL CLI so it won't use the model.

I'm not sure about the downloadable reports. @ormsbee might know?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mulby, that's very helpful.

I found the PR where @cahrens is working on the data downloads here(https://github.com/edx/edx-platform/pull/11167), and it's also using SQL instead of models, so I think we'll be covered on all fronts.

@efischer19
efischer19 force-pushed the efischer/soft_delete_sub branch 2 times, most recently from 927db70 to 1d70b57 Compare February 3, 2016 20:46
@efischer19 efischer19 changed the title Reset Student State via soft deletion Soft-delete Submissions to reset student state Feb 3, 2016
@ormsbee

ormsbee commented Feb 3, 2016

Copy link
Copy Markdown
Contributor

Sorry for coming late and asking a stupid question, but why is it necessary to delete their submission? It isn't enough to delete the submission_id that is in their student module state for the problem?

@efischer19

Copy link
Copy Markdown
Contributor Author

That's actually a really good question @ormsbee - the impetus for this work is https://openedx.atlassian.net/browse/TNL-3880.

The reason this is a bug that's only now appearing is staff tools - this block allows us to look up a submission for a student given a username, without checking the student's module state: https://github.com/edx/edx-ora2/blob/master/openassessment/xblock/staff_area_mixin.py#L338

Looking into it more just now, it seems that the reported buggy behavior only appears when using staff tools to "find" a "deleted" submission, this puts everything into a bad state (for the current staff user). However, refreshing the page gets everything back to where it needs to be.

So I suppose we could do a simple fix, and have that staff access codepath also check to ensure the submission is valid. But then again, we may end up in this position again if there's a different place that tries to get a "deleted" submission, since it's only "deleted" insofar as the student module drops it's record.

Comment thread submissions/api.py Outdated
cache_key = "submissions.submission.{}".format(sub.uuid)
cache.delete(cache_key)
sub.deleted = True
sub.save()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cache clearing needs to happen no matter which of the 3 unlinking options we end up choosing

@efischer19

Copy link
Copy Markdown
Contributor Author

This is the SQL that will be run with the new status column migration:

[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws sqlmigrate submissions 0003

BEGIN;
ALTER TABLE `submissions_submission` ADD COLUMN `status` varchar(1) DEFAULT 'A' NOT NULL;
ALTER TABLE `submissions_submission` ALTER COLUMN `status` DROP DEFAULT;

COMMIT;

name='status',
field=models.CharField(default=b'A', max_length=1, choices=[(b'D', b'Deleted'), (b'A', b'Active')]),
),
]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxrothman (and FYI @scottrish), here's the timing data I got from my sandbox. 90 seconds to apply the migration to a table with 700,000 rows.

mysql> show create procedure stuff_submissions_tables;
+--------------------------+--------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| Procedure                | sql_mode                                   | Create Procedure                                                                                                                                                                                                                                                                                                                                                                                       | character_set_client | collation_connection | Database Collation |
+--------------------------+--------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
| stuff_submissions_tables | STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=`root`@`localhost` PROCEDURE `stuff_submissions_tables`(in numRows int)
begin
declare i int;
set i = 1;
start transaction;
while i < numRows do
insert into submissions_studentitem values(i, uuid(), uuid(), uuid(), "openassessment");
insert into submissions_submission values (i, uuid(), 1, now(), now(), concat(uuid(), uuid(), uuid()), i);
set i = i+1;
end while;
commit;
end | utf8                 | utf8_general_ci      | utf8_general_ci    |
+--------------------------+--------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
1 row in set (0.00 sec)

mysql> call stuff_submissions_tables(700000);
Query OK, 0 rows affected (1 min 41.62 sec)

mysql> select count(*) from submissions_submission;
+----------+
| count(*) |
+----------+
|   699999 |
+----------+
1 row in set (0.14 sec)

mysql> exit
Bye
[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ time sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws migrate submissions 0003

Operations to perform:
  Target specific migration: 0003_submission_status, from submissions
Running migrations:
  Rendering model states... DONE
  Applying submissions.0003_submission_status... OK

real    1m29.847s
user    0m3.460s
sys 0m0.412s

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're going to have to make a call here on feasibility (@e0d devops and @scottrish product).

Using the search linked below, we're looking at 500-1000 requests per hour, or on the order of tens per minute. @maxrothman and I have estimated that, given that request rate and the above timing data for a database not under load, we're looking at an upper bound of several hundred request failures during the migration. Is this an acceptable outage? It will only apply to users who are hitting the submissions database, which is only used by ORA and has a cache that will remain unaffected.

http://splunk.edx.org/en-US/app/search/search?earliest=-7d%40h&latest=now&q=search%20index%3D%22prod-edx%22%20sourcetype%3Dedx%20%22submissions.api%22%20NOT%20%22(cached)%22%20%7C%20timechart%20span%3D1h%20count%20by%20log_level&display.page.search.tab=visualizations&display.general.type=visualizations&sid=1455135927.4182068

@efischer19

Copy link
Copy Markdown
Contributor Author

@maxrothman @e0d @scottrish Here's the data I got from running the new no-default migration. It's about a 50% reduction in time, so more like 2 minutes than 3 for production (probably). I've tested, and this does still require a table lock, causing errors for users making submissions during the migration. If we're not comfortable with this outage, we'll need to explore other options.

mysql> select count(*) from submissions_submission;
+----------+
| count(*) |
+----------+
|   700000 |
+----------+
1 row in set (0.12 sec)

mysql> select * from submissions_submission limit 10;
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
| id | uuid                                 | attempt_number | submitted_at               | created_at                 | raw_answer                                                                                                   | student_item_id |
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
|  1 | a52dbedc-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dbef6-d027-11e5-b22d-0a4b0a301c3fa52dbef9-d027-11e5-b22d-0a4b0a301c3fa52dbf01-d027-11e5-b22d-0a4b0a301c3f |               1 |
|  2 | a52dc2c6-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc2d0-d027-11e5-b22d-0a4b0a301c3fa52dc2d3-d027-11e5-b22d-0a4b0a301c3fa52dc2d6-d027-11e5-b22d-0a4b0a301c3f |               2 |
|  3 | a52dc48d-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc495-d027-11e5-b22d-0a4b0a301c3fa52dc497-d027-11e5-b22d-0a4b0a301c3fa52dc499-d027-11e5-b22d-0a4b0a301c3f |               3 |
|  4 | a52dc621-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc628-d027-11e5-b22d-0a4b0a301c3fa52dc62a-d027-11e5-b22d-0a4b0a301c3fa52dc62c-d027-11e5-b22d-0a4b0a301c3f |               4 |
|  5 | a5348fb8-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5348fcf-d027-11e5-b22d-0a4b0a301c3fa5348fd1-d027-11e5-b22d-0a4b0a301c3fa5348fd6-d027-11e5-b22d-0a4b0a301c3f |               5 |
|  6 | a53491ae-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a53491b6-d027-11e5-b22d-0a4b0a301c3fa53491b8-d027-11e5-b22d-0a4b0a301c3fa53491bb-d027-11e5-b22d-0a4b0a301c3f |               6 |
|  7 | a5376e32-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5376e3f-d027-11e5-b22d-0a4b0a301c3fa5376e41-d027-11e5-b22d-0a4b0a301c3fa5376e46-d027-11e5-b22d-0a4b0a301c3f |               7 |
|  8 | a5377060-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5377068-d027-11e5-b22d-0a4b0a301c3fa537706a-d027-11e5-b22d-0a4b0a301c3fa537706d-d027-11e5-b22d-0a4b0a301c3f |               8 |
|  9 | a53771ed-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a53771f4-d027-11e5-b22d-0a4b0a301c3fa53771f6-d027-11e5-b22d-0a4b0a301c3fa53771f8-d027-11e5-b22d-0a4b0a301c3f |               9 |
| 10 | a5377364-d027-11e5-b22d-0a4b0a301c3f |              1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a537736b-d027-11e5-b22d-0a4b0a301c3fa537736d-d027-11e5-b22d-0a4b0a301c3fa537736f-d027-11e5-b22d-0a4b0a301c3f |              10 |
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
10 rows in set (0.00 sec)

mysql> exit
Bye
[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws sqlmigrate submissions 0003
BEGIN;
ALTER TABLE `submissions_submission` ADD COLUMN `status` varchar(1) NULL;

COMMIT;
[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ time sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws migrate submissions 0003

Operations to perform:
  Target specific migration: 0003_submission_status, from submissions
Running migrations:
  Rendering model states... DONE
  Applying submissions.0003_submission_status... OK

real    1m7.989s
user    0m3.468s
sys 0m0.424s

@ormsbee

ormsbee commented Feb 11, 2016

Copy link
Copy Markdown
Contributor

Can we just add a new table, do a join, and only have values in that table
for non-default statuses?

On Wed, Feb 10, 2016 at 5:00 PM, Eric Fischer notifications@github.com
wrote:

@maxrothman https://github.com/maxrothman @e0d https://github.com/e0d
@scottrish https://github.com/scottrish Here's the data I got from
running the new no-default migration. It's about a 50% reduction in time,
so more like 2 minutes than 3 for production (probably). I've tested, and
this does still require a table lock, causing errors for users making
submissions during the migration. If we're not comfortable with this
outage, we'll need to explore other options.

mysql> select count() from submissions_submission;
+----------+
| count(
) |
+----------+
| 700000 |
+----------+
1 row in set (0.12 sec)

mysql> select * from submissions_submission limit 10;
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
| id | uuid | attempt_number | submitted_at | created_at | raw_answer | student_item_id |
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
| 1 | a52dbedc-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dbef6-d027-11e5-b22d-0a4b0a301c3fa52dbef9-d027-11e5-b22d-0a4b0a301c3fa52dbf01-d027-11e5-b22d-0a4b0a301c3f | 1 |
| 2 | a52dc2c6-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc2d0-d027-11e5-b22d-0a4b0a301c3fa52dc2d3-d027-11e5-b22d-0a4b0a301c3fa52dc2d6-d027-11e5-b22d-0a4b0a301c3f | 2 |
| 3 | a52dc48d-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc495-d027-11e5-b22d-0a4b0a301c3fa52dc497-d027-11e5-b22d-0a4b0a301c3fa52dc499-d027-11e5-b22d-0a4b0a301c3f | 3 |
| 4 | a52dc621-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a52dc628-d027-11e5-b22d-0a4b0a301c3fa52dc62a-d027-11e5-b22d-0a4b0a301c3fa52dc62c-d027-11e5-b22d-0a4b0a301c3f | 4 |
| 5 | a5348fb8-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5348fcf-d027-11e5-b22d-0a4b0a301c3fa5348fd1-d027-11e5-b22d-0a4b0a301c3fa5348fd6-d027-11e5-b22d-0a4b0a301c3f | 5 |
| 6 | a53491ae-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a53491b6-d027-11e5-b22d-0a4b0a301c3fa53491b8-d027-11e5-b22d-0a4b0a301c3fa53491bb-d027-11e5-b22d-0a4b0a301c3f | 6 |
| 7 | a5376e32-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5376e3f-d027-11e5-b22d-0a4b0a301c3fa5376e41-d027-11e5-b22d-0a4b0a301c3fa5376e46-d027-11e5-b22d-0a4b0a301c3f | 7 |
| 8 | a5377060-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a5377068-d027-11e5-b22d-0a4b0a301c3fa537706a-d027-11e5-b22d-0a4b0a301c3fa537706d-d027-11e5-b22d-0a4b0a301c3f | 8 |
| 9 | a53771ed-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a53771f4-d027-11e5-b22d-0a4b0a301c3fa53771f6-d027-11e5-b22d-0a4b0a301c3fa53771f8-d027-11e5-b22d-0a4b0a301c3f | 9 |
| 10 | a5377364-d027-11e5-b22d-0a4b0a301c3f | 1 | 2016-02-10 18:53:59.000000 | 2016-02-10 18:53:59.000000 | a537736b-d027-11e5-b22d-0a4b0a301c3fa537736d-d027-11e5-b22d-0a4b0a301c3fa537736f-d027-11e5-b22d-0a4b0a301c3f | 10 |
+----+--------------------------------------+----------------+----------------------------+----------------------------+--------------------------------------------------------------------------------------------------------------+-----------------+
10 rows in set (0.00 sec)

mysql> exit
Bye
[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws sqlmigrate submissions 0003
BEGIN;
ALTER TABLE submissions_submission ADD COLUMN status varchar(1) NULL;

COMMIT;
[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ time sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws migrate submissions 0003

Operations to perform:
Target specific migration: 0003_submission_status, from submissions
Running migrations:
Rendering model states... DONE
Applying submissions.0003_submission_status... OK

real 1m7.989s
user 0m3.468s
sys 0m0.424s


Reply to this email directly or view it on GitHub
#33 (comment).

@maxrothman

Copy link
Copy Markdown

@efischer19 could you post the SQL the new migration runs?

@efischer19

Copy link
Copy Markdown
Contributor Author

Sorry @maxrothman, meant to include that above.

[efischer19-sandbox] efischer19@efischer19 i-6fd3e6ea:~$ sudo -u www-data /edx/bin/python.edxapp /edx/bin/manage.edxapp lms --settings aws sqlmigrate submissions 0003

BEGIN;
ALTER TABLE `submissions_submission` ADD COLUMN `status` varchar(1) NULL;

COMMIT;

@ormsbee, we discussed your idea in planning this morning, and have decided that the amount of data isn't large enough to justify an extension table. From a product point of view, the small outage is acceptable.

The plan is now:

  • confirm with @maxrothman the extent of the service outage (currently estimated 2-3 minutes, maybe ~200 requests)
  • confirm behavior during the outage (should be a small server error, nothing that corrupts user's state, and able to be retried successfully after the window closes)
  • put up a warning banner ahead of the migration announcing what is happening
  • do the migration
  • take the banner down

@efischer19

Copy link
Copy Markdown
Contributor Author

@dianakhuang @robrap This PR is ready for review, can you give it a look when you get a chance?

FYI @cahrens - this goes with the other 2 you've already reviewed, feel free to skip it if you're busy with Fedx stuff though.

The problems with the global status message in https://openedx.atlassian.net/browse/TNL-4048 have been fixed via https://github.com/edx/edx-platform/pull/11525, which is going out in this week's release so that we can move forward with this release plan next week.

Comment thread submissions/api.py Outdated
sub.save(update_fields=["status"])

# Also clear out cached values
cache_key = "submissions.submission.{}".format(sub.uuid)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer just letting the 5 minute timeout take care of this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd have a function like get_submission_cache_key (or make... or create...), following whatever naming convention we've established for something like this. This function should be used all places the cache key is needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to ensure we're clear - the individual submission cache (keyed on submissions.submission.{}) does not have a timeout, and needs to be handled here. The top scores cache is what would timeout, and I agree that it probably doesn't need to be explicitly handled here.

@robrap

robrap commented Feb 12, 2016

Copy link
Copy Markdown

Looks good @efischer19. All of my comments are minor. Thanks.

@efischer19
efischer19 force-pushed the efischer/soft_delete_sub branch from 5bef451 to 3fc0558 Compare February 12, 2016 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants