0.01
No commit activity in last 3 years
No release in over 3 years
This gem will help setup partitioning on a table, based on its `timestamp` column. Once you have a table that is partitioned based on a timestamp, you will likely need to regularly add new partitions into the future, and drop older partitions to free up space. This gem can help carry out such routine activities as well.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

= 0.10.7
= 0.10.7
= 1.25.1
= 2.8.1
<= 1.7.0
= 3.0.0
= 0.9.1
 Project Readme

SqlPartitioner

Build Status Gem Version Coverage Status Dependency Status

SqlPartitioner provides a PartitionsManager class to help maintain partitioned tables in MySQL. If you have a table that is partitioned based on a timestamp, you will likely need to regularly add new partitions into the future as well as remove older partitions to free up space. This gem will help.

Supported Features

SqlPartitioner works with MySQL partitioned tables that are partitioned by a timestamp column, expressed as an integer representing a Unix epoch timestamp in either seconds or micro-seconds.

You can use ActiveRecord or DataMapper.

Supported functionality:

  • initializing partitioning on a table
  • adding new partitions of a given size (expressed in months or days)
  • removing partitions older than a given timestamp or number of days

You can run the above operations directly or pass a flag to only do a dry-run.

Unsupported Features

Does not yet support databases other than MySQL. Target table can only be partitioned by its timestamp column representing seconds or micro-seconds.

Getting Started

You'll need to require 'sql_partitioner'.

Here's an example for initializing a PartitionsManager instance, using DataMapper:

partition_manager = SqlPartitioner::PartitionsManager.new(
    :table_name        => 'my_partitioned_table', # target table for partitioning operations
    :time_unit         => :micro_seconds, # or :seconds, as appropriate for the table's `timestamp` column
    :lock_wait_timeout => 1, #(seconds)
    :adapter           => SqlPartitioner::DMAdapter.new(DataMapper.repository.adapter),
    :logger            => Logger.new(STDOUT)
)

If you are using ActiveRecord, you can instead supply the following for :adapter:

SqlPartitioner::ARAdapter.new(ActiveRecord::Base.connection)

Regarding the :lock_wait_timeout option: any partitioning statement must acquire a table lock on the partitioned table, and while it is waiting to acquire this lock, any subsequent queries on that table will be blocked and have to wait. It may take a long time to acquire a table lock if there were already long-running queries in progress. Therefore, setting a short timeout (e.g. 1 second) ensures the partitioning statement will timeout quickly, so any other SQL operations on that table will not be delayed. If the partitioning command times-out, it will have to be retried later. MySQL's default value for lock_wait_timeout is 1 year.

Initialize partitioning

Here's an example for initializing partitioning on the table. It will create partitions of size 30 days, as needed, to cover 90 days into the future:

days_into_future = 90
partition_size = 30
partition_size_unit = :days
dry_run = false
partition_manager.initialize_partitioning_in_intervals(days_into_future, partition_size_unit, partition_size, dry_run)

Adding partitions

Here's an example for appending partitions to cover time periods into the future. It will create partitions of size 30 days, as needed, to cover 180 days into the future:

days_into_future = 180
partition_size = 30
partition_size_unit = :days
dry_run = false
partition_manager.append_partition_intervals(partition_size_unit, partition_size, days_into_future, dry_run)

Here's an example for appending a single partition with the given name and "until" timestamp (using microseconds in this case):

partition_data = {'until_2014_11_01' => 1414870869000000}
dry_run = false
partition_manager.reorg_future_partition(partition_data, dry_run)

Dropping partitions

Here's an example for dropping partitions as needed to only cover 360 days of the past:

days_into_past = 360
dry_run = false
partition_manager.drop_partitions_older_than_in_days(days_into_past, dry_run)

Here's an example for dropping a single partition, until_2014_11_01, by name:

partition_names = ['until_2014_11_01']
dry_run = false
partition_manager.drop_partitions(partition_names, dry_run)

Suggested use:

The above operations can be helpful when creating a rake task that can initialize partitioning for a given table, and gets called periodically to add and remove partitions as needed.

Compatibility

Tested with Ruby 1.8.7 and 2.1.2, and MySQL 5.5.

Contributing

Pull requests welcome.

Maintained by

License

MIT License, see LICENSE