To expand on the second point, we have a cron job that runs a PHP script that finds records in a range of tables that are more than 90 days old and inserts them into backup/archive tables.
So we're never destroying the data, simply moving it out of the production tables.
Skipping over a LOT of detail, the script generally has this structure:
scan target tables for rows older than target date
put row IDs in an array
call archive function that...
CREATE TABLE IF NOT EXISTS archive_{$table} LIKE {$table}
INSERT IGNORE INTO archive_{$table} SELECT * FROM {$table} WHERE id IN ({$ids})
DELETE FROM {$table} WHERE id IN ({$ids})
It's more nuanced/complicated when dealing with the mailing tables but it essentially follows this flow.