rdb.py 4.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. from optparse import OptionParser
  5. from rdbtools import RdbParser, JSONCallback, DiffCallback, MemoryCallback, ProtocolCallback, PrintAllKeys, KeysOnlyCallback, KeyValsOnlyCallback
  6. from rdbtools.encodehelpers import ESCAPE_CHOICES
  7. VALID_TYPES = ("hash", "set", "string", "list", "sortedset")
  8. def main():
  9. usage = """usage: %prog [options] /path/to/dump.rdb
  10. Example : %prog --command json -k "user.*" /var/redis/6379/dump.rdb"""
  11. parser = OptionParser(usage=usage)
  12. parser.add_option("-c", "--command", dest="command",
  13. help="Command to execute. Valid commands are json, diff, justkeys, justkeyvals, memory and protocol", metavar="FILE")
  14. parser.add_option("-f", "--file", dest="output",
  15. help="Output file", metavar="FILE")
  16. parser.add_option("-n", "--db", dest="dbs", action="append",
  17. help="Database Number. Multiple databases can be provided. If not specified, all databases will be included.")
  18. parser.add_option("-k", "--key", dest="keys", default=None,
  19. help="Keys to export. This can be a regular expression")
  20. parser.add_option("-o", "--not-key", dest="not_keys", default=None,
  21. help="Keys Not to export. This can be a regular expression")
  22. parser.add_option("-t", "--type", dest="types", action="append",
  23. help="""Data types to include. Possible values are string, hash, set, sortedset, list. Multiple typees can be provided.
  24. If not specified, all data types will be returned""")
  25. parser.add_option("-b", "--bytes", dest="bytes", default=None,
  26. help="Limit memory output to keys greater to or equal to this value (in bytes)")
  27. parser.add_option("-l", "--largest", dest="largest", default=None,
  28. help="Limit memory output to only the top N keys (by size)")
  29. parser.add_option("-e", "--escape", dest="escape", choices=ESCAPE_CHOICES,
  30. help="Escape strings to encoding: %s (default), %s, %s, or %s." % tuple(ESCAPE_CHOICES))
  31. (options, args) = parser.parse_args()
  32. if len(args) == 0:
  33. parser.error("Redis RDB file not specified")
  34. dump_file = args[0]
  35. filters = {}
  36. if options.dbs:
  37. filters['dbs'] = []
  38. for x in options.dbs:
  39. try:
  40. filters['dbs'].append(int(x))
  41. except ValueError:
  42. raise Exception('Invalid database number %s' %x)
  43. if options.keys:
  44. filters['keys'] = options.keys
  45. if options.not_keys:
  46. filters['not_keys'] = options.not_keys
  47. if options.types:
  48. filters['types'] = []
  49. for x in options.types:
  50. if not x in VALID_TYPES:
  51. raise Exception('Invalid type provided - %s. Expected one of %s' % (x, (", ".join(VALID_TYPES))))
  52. else:
  53. filters['types'].append(x)
  54. out_file_obj = None
  55. try:
  56. if options.output:
  57. out_file_obj = open(options.output, "wb")
  58. else:
  59. # Prefer not to depend on Python stdout implementation for writing binary.
  60. out_file_obj = os.fdopen(sys.stdout.fileno(), 'wb')
  61. try:
  62. callback = {
  63. 'diff': lambda f: DiffCallback(f, string_escape=options.escape),
  64. 'json': lambda f: JSONCallback(f, string_escape=options.escape),
  65. 'justkeys': lambda f: KeysOnlyCallback(f, string_escape=options.escape),
  66. 'justkeyvals': lambda f: KeyValsOnlyCallback(f, string_escape=options.escape),
  67. 'memory': lambda f: MemoryCallback(PrintAllKeys(f, options.bytes, options.largest),
  68. 64, string_escape=options.escape),
  69. 'protocol': lambda f: ProtocolCallback(f, string_escape=options.escape)
  70. }[options.command](out_file_obj)
  71. except:
  72. raise Exception('Invalid Command %s' % options.command)
  73. parser = RdbParser(callback, filters=filters)
  74. parser.parse(dump_file)
  75. finally:
  76. if options.output and out_file_obj is not None:
  77. out_file_obj.close()
  78. if __name__ == '__main__':
  79. main()